Самый простой способ объединить релиз в один файл JAR

Существует ли инструмент или скрипт, который легко объединяет несколько файлов JAR в один файл JAR? Бонусом было бы легко установить манифест основного файла и сделать его исполняемым.

Конкретный случай - реструктурированный текстовый инструмент Java. Я хотел бы запустить его с чем-то вроде:

java -jar rst.jar

Насколько я могу судить, он не имеет зависимостей, которые указывают на то, что он не должен быть простым однофайловым инструментом, но загруженный ZIP-файл содержит много библиотек.

      0  11-30-07 10:01   jrst-0.8.1/
    922  11-30-07 09:53   jrst-0.8.1/jrst.bat
    898  11-30-07 09:53   jrst-0.8.1/jrst.sh
   2675  11-30-07 09:42   jrst-0.8.1/readmeEN.txt
 108821  11-30-07 09:59   jrst-0.8.1/jrst-0.8.1.jar
   2675  11-30-07 09:42   jrst-0.8.1/readme.txt
      0  11-30-07 10:01   jrst-0.8.1/lib/
  81508  11-30-07 09:49   jrst-0.8.1/lib/batik-util-1.6-1.jar
2450757  11-30-07 09:49   jrst-0.8.1/lib/icu4j-2.6.1.jar
 559366  11-30-07 09:49   jrst-0.8.1/lib/commons-collections-3.1.jar
  83613  11-30-07 09:49   jrst-0.8.1/lib/commons-io-1.3.1.jar
 207723  11-30-07 09:49   jrst-0.8.1/lib/commons-lang-2.1.jar
  52915  11-30-07 09:49   jrst-0.8.1/lib/commons-logging-1.1.jar
 260172  11-30-07 09:49   jrst-0.8.1/lib/commons-primitives-1.0.jar
 313898  11-30-07 09:49   jrst-0.8.1/lib/dom4j-1.6.1.jar
1994150  11-30-07 09:49   jrst-0.8.1/lib/fop-0.93-jdk15.jar
  55147  11-30-07 09:49   jrst-0.8.1/lib/activation-1.0.2.jar
 355030  11-30-07 09:49   jrst-0.8.1/lib/mail-1.3.3.jar
  77977  11-30-07 09:49   jrst-0.8.1/lib/servlet-api-2.3.jar
 226915  11-30-07 09:49   jrst-0.8.1/lib/jaxen-1.1.1.jar
 153253  11-30-07 09:49   jrst-0.8.1/lib/jdom-1.0.jar
  50789  11-30-07 09:49   jrst-0.8.1/lib/jewelcli-0.41.jar
 324952  11-30-07 09:49   jrst-0.8.1/lib/looks-1.2.2.jar
 121070  11-30-07 09:49   jrst-0.8.1/lib/junit-3.8.1.jar
 358085  11-30-07 09:49   jrst-0.8.1/lib/log4j-1.2.12.jar
  72150  11-30-07 09:49   jrst-0.8.1/lib/logkit-1.0.1.jar
 342897  11-30-07 09:49   jrst-0.8.1/lib/lutinwidget-0.9.jar
2160934  11-30-07 09:49   jrst-0.8.1/lib/docbook-xsl-nwalsh-1.71.1.jar
 301249  11-30-07 09:49   jrst-0.8.1/lib/xmlgraphics-commons-1.1.jar
  68610  11-30-07 09:49   jrst-0.8.1/lib/sdoc-0.5.0-beta.jar
3149655  11-30-07 09:49   jrst-0.8.1/lib/xalan-2.6.0.jar
1010675  11-30-07 09:49   jrst-0.8.1/lib/xercesImpl-2.6.2.jar
 194205  11-30-07 09:49   jrst-0.8.1/lib/xml-apis-1.3.02.jar
  78440  11-30-07 09:49   jrst-0.8.1/lib/xmlParserAPIs-2.0.2.jar
  86249  11-30-07 09:49   jrst-0.8.1/lib/xmlunit-1.1.jar
 108874  11-30-07 09:49   jrst-0.8.1/lib/xom-1.0.jar
  63966  11-30-07 09:49   jrst-0.8.1/lib/avalon-framework-4.1.3.jar
 138228  11-30-07 09:49   jrst-0.8.1/lib/batik-gui-util-1.6-1.jar
 216394  11-30-07 09:49   jrst-0.8.1/lib/l2fprod-common-0.1.jar
 121689  11-30-07 09:49   jrst-0.8.1/lib/lutinutil-0.26.jar
  76687  11-30-07 09:49   jrst-0.8.1/lib/batik-ext-1.6-1.jar
 124724  11-30-07 09:49   jrst-0.8.1/lib/xmlParserAPIs-2.6.2.jar

Как видите, желательно не делать это вручную.

До сих пор я пробовал только AutoJar и ProGuard, которые довольно легко запустить. Кажется, что есть некоторая проблема с постоянным пулом в файлах JAR.

По-видимому, Jrst немного сломан, поэтому я постараюсь исправить это. Мавен pom.xml файл тоже явно сломан, так что мне придется это исправить, прежде чем исправлять jrst... Я чувствую себя баг-магнитом:-)


Обновление: я никогда не удосужился исправить это приложение, но я проверил в Eclipse"Runnable JAR export wizard", основанный на толстом JAR. Я нашел это очень простым в использовании для развертывания моего собственного кода.

Некоторые из других замечательных предложений могут быть лучше для сборок в среде без Eclipse, oss, вероятно, должен сделать хорошую сборку с использованием Ant. (Maven, пока что только что причинял мне боль, но другие любят это.)

13 ответов

Решение

Eclipse 3.4 Мастер экспорта JAR-файлов JNT.

В Eclipse 3.5 это было расширено. Теперь вы можете выбрать способ обработки файлов JAR, на которые вы ссылаетесь.

Муравьев zipfileset делает работу

<jar id="files" jarfile="all.jar">
    <zipfileset src="first.jar" includes="**/*.java **/*.class"/>
    <zipfileset src="second.jar" includes="**/*.java **/*.class"/>
</jar>

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

One-JAR использует пользовательский загрузчик классов, который может перемещаться по вложенным ресурсам. Посмотрите на файл.bat в загрузке, он выглядит как org.codelutin.jrst.JRST в jrst-0.8.1.jar является основным классом, поэтому ваш манифест должен выглядеть так:

Main-Class: com.simontuffs.onejar.Boot
One-Jar-Main-Class: org.codelutin.jrst.JRST

Действительно здорово, что One-JAR будет обрабатывать передачу аргументов командной строки для вас. Путь к классам обрабатывается пользовательским загрузчиком классов, при условии, что все необходимые ресурсы объединены в один JAR.

Самый простой способ использовать One-JAR - с помощью ant; есть специальная задача муравья "one-jar", которая работает следующим образом (при условии, что ваш манифест называется "rst.mf"):

<target name="jar-rst">
    <one-jar destfile="rst.jar" manifest="rst.mf">
        <main jar="jrst-0.8.1.jar" />
        <lib>
            <fileset dir="${pathToJars}">
                <include name="batik-util-1.6-1.jar" />
                <include name="icu4j-2.6.1.jar" />
                <include name="commons-collections-3.1.jar" />
                <!-- Snip -->
            </fileset>
        </lib>
    </one-jar>
</target>

Если вы пользователь Maven, обычно плагин сборки делает то, что вы хотите, или, возможно, плагин затенения, а в некоторых случаях и комбинацию.

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

mvn assembly:assembly

Или, если у вас есть более особые дела, одна из других целей. Все JAR-файлы, которые нужно включить, выбираются средством разрешения зависимостей Maven. Если вы используете плагин Shade, он обычно является частью цели установки, и в одном конкретном проекте, который я делаю сейчас, я делаю

mvn install
mvn assembly:single

assembly:single Цель состоит в том, чтобы обойти жизненные проблемы, в данном случае в приложении Spring.

Существует ProGuard, который не только упаковывает ваши JAR-файлы в один, но также может оптимизировать, очищать или скрывать ваши файлы классов, делая результирующий JAR-файл намного меньше, чем сумма всех JAR-файлов ранее.

Я на самом деле пробовал ProGuard с помощью инструмента JRST, и это, как вы сообщили. Я попытался отследить проблему и обнаружил, что она связана с ошибкой в библиотеке ICU4J, на которую ссылается jrst. Проблема в том, что используемая версия ICU сейчас сильно устарела. Поэтому я заменил icu.jar файл с версией 3.2 ICU4J. Теперь ProGuard находит кучу других ошибок / предупреждений о несоответствиях с библиотеками JRST.

Я предполагаю, что ProGuard работает, как и ожидалось, но библиотеки Jrst просто не согласованы. Я не знаю, сможете ли вы сделать гораздо больше, чем поговорить с его разработчиками, поскольку они должны проверять и обновлять зависимости проекта.

(по материалам Андриана):

<jar id="files" jarfile="all.jar">
  <zipgroupfileset dir="${library.dir}" includes="*.jar" excludes="test-helper.jar"/>
  <zipfileset src="first.jar" includes="**/*.java **/*.class"/>
  <zipfileset src="second.jar" includes="**/*.java **/*.class"/>
  <fileset dir=".">
    <include name="LICENSE"/>
    <include name="NOTICE"/>
  </fileset>
</jar>

Вы можете использовать JarJar, который будет использовать теневое копирование пакетов, чтобы убедиться, что ваш JAR-файл не конфликтует с другими.

One-JAR 0.97 был только что выпущен на http://one-jar.sourceforge.net/, и он был расширен с поддержкой таких фреймворков, как Spring и Guice, что может создавать проблемы для других подходов. Он также обрабатывает инверсию загрузчика классов - когда некоторые файлы JAR являются внешними по отношению к One-JAR (например, драйверы JDBC, которые могут не поставляться в комплекте).

One-JAR - это командная строка с плагинами Ant и Maven 2. Это также просто собрать, используя инструмент "jar".

Я также могу порекомендовать Eclipse Jar Exporter (Runnable), о котором написал Ференс Хехлер: он проделал большую работу, придумав простой подход к упаковке набора файлов JAR. Он и я работали над One-JAR, но Jar Exporter основан на другой кодовой базе.

Или используя плагин сборки Maven (сборка mvn: сборка)

Существует инструмент autojar, который сканирует ваш байт-код и компилирует файл.jar с классами, которые он находит, включая ссылочные (импортированные) классы.

Не всегда работает с чем-то вроде Spring, где вы указываете имена классов в конфигурации, и это загружается платформой.

Я думаю, что инструмент, который вам нужен здесь, это JarSplice: http://ninjacave.com/jarsplice

Он не требует Ant или Maven, имеет собственный графический интерфейс, он прост в использовании и делает именно то, что вы просили -> Объединяет содержимое нескольких jar-файлов в один (обратите внимание, что по-прежнему необходимо добавить собственный загрузчик классов).

Вы должны использовать плагин затенения Maven, чтобы сделать это. Я часто использую Maven для создания автономного файла JAR, и это настолько мощный

Узнать больше:

http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html

Похоже, Apache Ant - это то, что вы ищете.

Другие вопросы по тегам