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

Путь к классу, включая JAR в JAR

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

Если вы собираете с помощью 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" />

был реж с наружными банками. И что это...

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

Если у вас есть среда разработки eclpise, вам просто нужно экспортировать JAR и выбрать "Библиотеки требуемых пакетов в сгенерированный JAR". eclipse автоматически добавит требуемые зависимые JAR в сгенерированный JAR, а также сгенерирует некоторый загрузчик пользовательских классов eclipse, который автоматически загружает эти JAR.

Ответ 10

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

Ответ 12

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

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

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

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