Подтвердить что ты не робот

Чистый способ объединить несколько банок? Предпочтительно использовать Ant

У меня есть зависимости от исполнения на некоторых внешних баночках, которые я хотел бы "перекрасить" в одну банку. Эти внешние зависимости хранятся в каталоге external_jars, и я хотел бы иметь возможность не перечислять их все (т.е. Не нужно менять скрипты сборки, если меняют зависимости). Любые мысли?

Google дал мне хороший ответ о том, как это сделать - если вы не возражаете, чтобы перечислять каждую банку как зависимость:

http://markmail.org/message/zijbwm46maxzzoo5

Грубо говоря, я хочу что-то по строкам следующего, которое объединило бы все банки в каталоге lib в out.jar(с некоторыми нормальными правилами перезаписи).

jar -combine -out out.jar -in lib/*.jar
4b9b3361

Ответ 1

Просто используйте zipgroupfileset с Ant Задача zip

<zip destfile="out.jar">
    <zipgroupfileset dir="lib" includes="*.jar"/>
</zip>

Это позволит сгладить содержимое всех библиотек jar-библиотек.

Ответ 2

Владимир ответ правильный, но я чувствую, что то, что он предлагает, предполагает переупаковку всех банок в одном большом out.jar, который затем загружается в Ant Jar task как один <zipfileset> или что-то в этом роде. Этот двухэтапный подход не нужен. Я не уверен, связано ли это с версией Ant, но у меня есть Ant 1.7.1, а задача <jar> понимает <zipgroupfileset>, что позволяет напрямую загружать все содержимое сторонних банках.

<jar destfile="MyApplication.jar">
  <zipgroupfileset dir="lib" includes="*.jar" /> 
  <!-- other options -->
  <manifest>
    <attribute name="Main-Class" value="Main.MainClass" />
  </manifest>
</jar>

Ответ 4

Попробуйте сначала извлечь JAR в сортировочный каталог:

<target name="combine-jars">
    <mkdir dir="${marshall.dir}"/>
    <unzip dest="${marshall.dir}">
        <fileset dir="${external.jar.dir}">
            <include name="**/*.jar"/>
        </fileset>
    </unzip>
    <jar destfile="${combined.jar}" basedir="${marshall.dir"}>
    <delete dir="${marshall.dir}"/>
</target>

Где ${marshall.dir} - временный каталог, ${external.jar.dir} - это место, где вы сохраняете JAR, а ${combined.jar} - целевой JAR.

Ответ 5

Если вы используете maven, почему бы и нет?:) Просто используйте плагин maven-shade, работает как шарм!

  <project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.5</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>com.YOUR_COMPANY.YOUR_MAIN_CLASS</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Ответ 6

Это мое решение:

<target name="-post-jar">
    <echo>Packaging ${application.title} into a single JAR</echo>

    <jar destfile="${basedir}${file.separator}${dist.dir}${file.separator}_${ant.project.name}_.jar">
        <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}" includes="${ant.project.name}.jar"/>
        <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}${file.separator}lib" includes="*.jar"/>
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
</target>

Ответ 7

Считаете ли вы использование Maven или какой-либо другой системы, которая автоматически управляет вашими зависимостями? Тогда вам не нужно будет указывать, где находится каждая библиотека, каковы их имена и какие транзитные зависимости имеют ваши прямые зависимости. Вы просто указываете в одном месте, что такое зависимость и ее версия, и система будет заботиться о загрузке библиотек, настройке пути к классам и создании проекта.

Ответ 8

Вопрос хорошо ответил. Я хотел упомянуть один инструмент, который мне пригодится - One-Jar. One-Jar обрабатывает ресурсы более чисто (сохраняя их все). Это более полезно, если код должен обрабатывать файлы MANIFEST.

Пример XML, скопированный с веб-сайта..

<import file="one-jar-ant-task.xml"/>   

    <target name="hello" depends="init">
        <!-- Build lib.jar -->   
        <javac destdir="${classes.dir}/lib">
            <src path="${lib.dir}" />
        </javac>
        <jar destfile="${build.dir}/lib.jar" >
            <fileset dir="${classes.dir}/lib"/>
        </jar>   
        <!-- Build classes for main.jar -->   
        <javac destdir="${classes.dir}/src">
            <src path="${src.dir}" />
            <classpath path="${build.dir}/lib.jar"/>   
        </javac>
        <!-- Construct the One-JAR file -->   
        <one-jar destfile="hello.jar" manifest="hello.mf">
            <main>
                <!-- Construct main.jar from classes and source code -->
                <fileset dir="${classes.dir}/src"/>
            </main>
            <lib>
                <fileset file="${build.dir}/lib.jar" />
            </lib>
        </one-jar>
        <echo>
          Now you can run the Hello One-JAR example using 
          $ java -jar hello.jar
        </echo>   

    </target>

Ответ 9

Ну, я не так много занимаюсь программированием, но что-то более простое работало для меня... если бы речь шла об объединении файлов jar в одном. Конечно, это ручное, грязное решение. Я просто разогнал все следы... и затем создал новый tar файл, добавив все каталоги, сформированные путем разворачивания в новый tar файл. это сработало.

Ответ 10

Maven или другие инструменты сборки не могут "управлять" разрешением нескольких версий файлов классов. Фактически, Maven вызывает эти проблемы в первую очередь благодаря транзитивному включению всех файлов jar вниз, которые явно не требуются для проекта.

Предположим, что где-то в транзитивном замыкании проекта (все библиотеки и модули, необходимые для проекта, и все его зависимые проекты, рекурсивно) есть две версии файла класса. Как мог Maven, возможно, узнать, какой из них "правильный"? какой из них был предназначен программистом?

Это невозможно, потому что эта информация была потеряна, когда явные зависимости были выброшены в пользу транзитивных (для сохранения XML-ввода).

Ответ 11

Если вы строите с помощью ant (я использую ant из eclipse), вы можете просто добавить дополнительные файлы jar говоря ant, чтобы добавить их... Не обязательно лучший метод, если у вас есть проект, поддерживаемый несколькими людьми, но он работает для одного человека и прост.

например, моя цель, которая создавала файл .jar:

<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    <manifest>
        <attribute name="Author" value="ntg"/>
        ................................
        <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    </manifest>
</jar>

Я просто добавил одну строку, чтобы сделать это:

<jar ....">
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
    <manifest>
        ................................
    </manifest>
</jar>

где

<property name="external-lib-dir" value="C:\...\eclipseWorkspace\Filter\external\...\lib" />

был гир с внешними баночками. И это... Вы можете добавить несколько тегов zipgroupfileset.