Можно ли упаковать все зависимости jar в одной большой банке?

Я знаю, что это не "лучшая практика", но могу ли я включить все зависимости в одну большую банку?

Ответ 1

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

Ответ 2

Мое чувство состоит в том, что вызов One-Jar производительности ужасный и бедный несправедлив. Для приложений с умеренным размером можно ожидать, что запуск будет занимать пару секунд дольше (что не влияет на экран заставки JVM, хотя). Накладные расходы на память в десятки мегабайт незначительны для большинства сред, за исключением, возможно, встроенных систем. Кроме того, One-Jar способен автоматически извлекать некоторые файлы в файловую систему, что избавляет от необходимости разработки установщика в моем случае.

Ниже приведена попытка количественно оценить влияние производительности, введенное One-Jar на мое приложение. Это приложение GUI на основе Swing, состоящее из 352 классов, запутанных с ProGuard 4.5b2. One-Jar 0.96 используется для объединения результирующих классов с библиотеками на 12 МБ (ODFDOM, Saxon HE, Xerces, Jaxen, VLDocking, Apache Commons и т.д.). Я сравнил производительность запутанной банки с той же банкой, обработанной One-Jar.

  • Начиная с JVM, начинаем с начала метода main(): 0.5 с без одной-на-1 и 1.7 с One-Jar. Начиная с JVM начинают появляться окна приложения на экране: 2.3s без One-Jar и 3.4s с One-Jar. Таким образом, One-Jar добавляет 1,1 к времени запуска.
  • One-Jar не увеличит задержку между запуском JVM и заставкой, появляющейся на экране (если реализован через манифест jar), поэтому увеличение времени запуска не слишком раздражает для интерактивных приложений.
  • Мы говорим о загрузчике классов, поэтому не должно влиять на скорость выполнения кода, если вы не используете динамическую загрузку классов.
  • Глядя на статистику JVM (через jconsole), показано, что версия One-Jar'red занимает больше памяти кучи. Для моего приложения накладные расходы составляют порядка десятков МБ. Я видел такие цифры, как 16MB против 40MB, 306MB против 346MB, 131MB против 138MB, в зависимости от того, сколько пользовательских данных обрабатывает приложение, и теперь уже давно сборщик мусора был выполнен.

Вышеуказанное время было получено, взяв метку времени перед запуском JVM из оболочки Linux, в начале метода main() и обработчика события windowOpened() моего окна приложения. Измерения проводились на не очень быстром ноутбуке D820 с двухъядерным 1 ГГц процессором и 2G или RAM с Ubuntu 8.04.

Надеюсь, что это поможет.

Ответ 4

Используя старый добрый Ant: просто используйте zipgroupfileset с Ant Задача zip

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

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

Ответ 5

One-JAR загружает все баны зависимости в память при запуске. Это может звучать ужасно неэффективно, но никто не жаловался мне об этом, так как он был выпущен в 2004 году. Вероятный эффект предварительной загрузки - это общая скорость загрузки классов для приложения, поскольку загрузчику классов не нужно многократно проверять путь к классам для ресурсов и классов по мере запуска приложения: все hashmapped.

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

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

Ответ 6

Если вы хотите сделать это, вы можете использовать инструмент Jar Jar Links, который сделает это за вас. Никогда не использовал его, но трудно забыть имя.

Ответ 7

Часто вы можете, но иногда есть необычные юридические или технические причины.

  • Право:. Например, мы обнаружили, что в то время, когда мы хотели, мы не могли объединить файлы jar JavaMail вместе в один большой пакет вместе с остальной частью нашего приложения, но лицензионное соглашение говорит, что мы должны были их разделить.

  • Технический: Другая проблема может заключаться в том, что пользовательские загрузчики классов ищут определенные ресурсы или классы внутри определенных файлов jar. Это часто происходит в контексте контейнеров для серверов приложений или ESB.

Как: Чтобы сделать это, просто развяжите все в один каталог, а затем перестройте банку. Возможно, вам придется настроить некоторые настройки в папке META-INF, чтобы удалить запросы на загрузку дополнительных банок и обработать случай, когда у каждого из них каждый класс имеет класс по умолчанию. Есть некоторые сторонние утилиты, которые могут помочь, но если вы не знаете, что они делают, вы должны быть осторожны.

Ответ 8

  • Вы можете развязать файлы и переупаковать их с помощью командной строки

  • Вы можете использовать [uberjar]

  • Вы можете использовать fatjar

Ответ 9

Eclipse 3.4 и выше позволяют это сделать. Щелкните правой кнопкой мыши свой проект, выберите "Извлечь" и перейдите к опции "Runnable Jar". Выберите "Далее". Выберите нужные параметры и нажмите и отпустите. Также я напоминаю, что эта функциональность достигается с использованием тех же или подобных библиотек, которые использует FatJar (упомянутый выше).

Ответ 10

Просто для полноты, ProGuard будет делать это за вас, а также при необходимости запутывать и сокращать JAR. Последняя функция особенно полезна для создания JAR окончательного развертывания.

Ответ 11

Также помните, что .jar файлы - это .zip файлы под обложками. Вы можете использовать свои любимые инструменты zip для (re) их упаковки. В этом случае вам придется иметь дело с файлом манифеста.