2008-10-08 5 views

ответ

85

Если вы пытаетесь создать единую банку, содержащую ваше приложение, и это необходимые библиотеки, для этого есть два способа (я знаю). Первый - One-Jar, в котором используется специальный загрузчик классов, позволяющий встраивать банки. Второй - UberJar, (или Shade), который взрывает включенные библиотеки и помещает все классы в банку верхнего уровня.

Следует также упомянуть, что UberJar и Shade являются плагинами для Maven1 и Maven2 соответственно. Как уже упоминалось ниже, вы также можете использовать плагин сборки (который на самом деле гораздо более мощный, но гораздо сложнее для правильной настройки).

+64

Итак, вот мы, 5 лет спустя. Похоже, это все еще так. Очень грустно :( – T3rm1 2013-08-06 06:49:19

+1

Лучший способ, которым я знаю сейчас, - использовать артефакт IntelliJ jar. Он извлекает все классы из зависимых банок и помещает их в вашу одну банку. – enl8enmentnow 2014-01-25 17:50:05

+1

Это невозможно в некоторых ситуациях, например, когда вы используете JCE-реализации, такие как BouncyCastle, которые должны быть подписаны. – debuti 2014-08-11 11:44:43

6

Не забудьте написать свой собственный загрузчик классов. Вы можете добавить банки в путь класса jar, но они должны быть расположены друг с другом, а не содержать в основном банке.

2

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

1

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

2

Я использую maven для своих сборщиков java, у которых есть плагин под названием maven assembly plugin.

Он делает то, что ваш вопрос, но как и некоторые другие предложения описывают - по существу, взрывая все зависимые банки и комбинируя их в одну банку

49

Вы не хотите использовать эти решения «взрываются содержимое JAR». Они определенно усложняют работу над материалом (поскольку все взорвано на одном уровне). Кроме того, могут быть конфликты именования (не должно происходить, если люди используют правильные пакеты, но вы не можете всегда контролировать это).

Функция, которую вы хотите, является одним из top 25 Sun RFEs: RFE 4648386, которое Солнце в своей бесконечной мудрости обозначило как имеющее низкий приоритет. Мы можем только надеяться, что Sun проснется ...

В то же время лучшим решением, с которым я столкнулся (которое я хочу, чтобы Sun копировал в JDK), является использование пользовательского загрузчика классов JarClassLoader.

22

Используйте zipgroupfileset тег (использует те же атрибуты, как набора файлов тегов); он распакует все файлы в каталоге и добавит в ваш новый файл архива. Дополнительная информация: http://ant.apache.org/manual/Tasks/zip.html

Это очень полезный способ обойти эту проблему банку-в-банке - я знаю, потому что я гугле именно этот StackOverflow вопрос, пытаясь выяснить, что делать. Если вы хотите упаковать банку или папку баночек в ваш построенном банк с Ant, то забудьте обо всей этом пути к классам или третьей стороны плагин вещь, все, что вам нужно сделать, это (в Ant):

<jar destfile="your.jar" basedir="java/dir"> 
    ... 
    <zipgroupfileset dir="dir/of/jars" /> 
</jar> 
8

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

, например, моя цель, которая строит .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" /> 

был с внешними баночками. И вот и все ...

26

После некоторых исследований я нашел метод, который не требует maven или стороннего расширения/программы.

Вы можете использовать «Class-Path» в вашем файле манифеста.

Например:

Создать файл манифеста MANIFEST.MF

Manifest-Version: 1.0 
Created-By: Bundle 
Class-Path: ./custom_lib.jar 
Main-Class: YourMainClass 

Скомпилировать все классы и запустить jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar

c стенды для создания архива f означает, что вы хотите, чтобы указать файл v для подробного ввода m означает, что мы будем ss файл манифеста

Убедитесь, что вы включили lib в банку. Вы должны иметь возможность запускать банку обычным способом.

на основе: http://www.ibm.com/developerworks/library/j-5things6/

вся другая информация, вам нужно о классовой пути вы найдете here

1

Ну, есть очень простой способ, если вы используете Eclipse.

Экспортируйте проект как файл Runnable Jar (щелкните правой кнопкой мыши папку проекта из Eclipse, выберите «Экспорт ...»). Когда вы настраиваете параметры экспорта, обязательно выберите «Извлечь требуемые библиотеки в сгенерированный Jar». Имейте в виду, выберите «Извлечь ...» и не «Необходимые библиотеки ...».

Дополнительно: Вы должны выбрать конфигурацию запуска в настройках экспорта. Таким образом, вы всегда можете создать пустую main() в каком-то классе и использовать ее для вашей конфигурации запуска.

В любом случае, это не гарантировано для работы в 100% случаев - как вы заметите всплывающее сообщение, сообщающее вам убедиться, что вы проверяете лицензии на файлы Jar, которые вы включаете, и что-то в этом роде не копирование файлов подписи. Тем не менее, я делаю это для лет и никогда не сталкивался с проблемой.

2

Если у вас есть Eclpise IDE, вам просто нужно экспортировать JAR и выбрать «Package Required libraries in generated JAR». eclipse автоматически добавит требуемые зависимые JAR в сгенерированный JAR, а также сгенерирует некоторый загрузчик пользовательских классов eclipse, который автоматически загружает эти JAR.

Смежные вопросы