Classpath включая JAR в JAR - PullRequest
       52

Classpath включая JAR в JAR

126 голосов
/ 08 октября 2008

Можно ли указать Java classpath, включающий файл JAR, содержащийся в другом файле JAR?

Ответы [ 12 ]

91 голосов
/ 08 октября 2008

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

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

50 голосов
/ 24 февраля 2010

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

Функция, которую вы хотите, - это одна из лучших 25 РЧЭ Sun : РСЕ 4648386 , которую Sun в своей бесконечной мудрости определила как имеющую низкий приоритет. Мы можем только надеяться, что Солнце проснется ...

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

29 голосов
/ 14 февраля 2014

После некоторых исследований я нашел метод, который не требует 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 означает, что мы передадим пользовательский файл манифеста

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

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

всю другую необходимую вам информацию о пути к классам вы найдете здесь

22 голосов
/ 09 сентября 2011

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

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

<jar destfile="your.jar" basedir="java/dir">
  ...
  <zipgroupfileset dir="dir/of/jars" />
</jar>
8 голосов
/ 25 апреля 2012

Если вы строите с помощью ant (я использую ant из eclipse), вы можете просто добавить дополнительные файлы 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" />

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

6 голосов
/ 08 октября 2008

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

2 голосов
/ 30 июля 2015

Если у вас есть eclpise IDE, вам просто нужно экспортировать JAR и выбрать «Пакет обязательных библиотек в сгенерированный JAR». eclipse автоматически добавит необходимые зависимые JAR-файлы в сгенерированный JAR-файл, а также сгенерирует некоторый загрузчик пользовательских классов eclipse, который автоматически загрузит эти JAR-файлы.

2 голосов
/ 08 октября 2008

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

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

2 голосов
/ 08 октября 2008

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

1 голос
/ 21 февраля 2014

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

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

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

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

...