openjdk.ruOpenJDK на русском

JEP 392: Packaging Tool

Инструмент упаковки приложений

ОтветственныйAndy Herrick
ТипFeature
ОбластьJDK
СтатусClosed / Delivered
Выпуск16
Компонентtools / jpackage
Обсуждениеcore dash libs dash dev at openjdk dot java dot net
ТрудоёмкостьS
ДлительностьS
Связан сJEP 343: Packaging Tool (Incubator)
РецензентыAlexander Matveev, Alexey Semenyuk, Kevin Rushforth, Philip Race
ОдобренBrian Goetz
Создан2020/06/17 14:57
Обновлён2021/02/19 20:03
Задача8247768

Аннотация

Предоставить инструмент jpackage для упаковки автономных Java-приложений.

История

Инструмент jpackage появился в JDK 14 в статусе Incubator (инкубационный модуль) в рамках JEP 343. В JDK 15 он остался в статусе Incubator, чтобы было время собрать дополнительные отзывы. Теперь он готов выйти из статуса Incubator и стать возможностью, готовой к промышленному использованию. Вследствие этого перехода имя модуля jpackage изменится с jdk.incubator.jpackage на jdk.jpackage.

Единственное существенное изменение по сравнению с JEP 343 состоит в том, что мы заменили параметр --bind-services более общим параметром --jlink-options, описанным ниже.

Цели

Создать инструмент упаковки на основе устаревшего инструмента JavaFX javapackager, который:

  • Поддерживает нативные форматы пакетов, чтобы конечные пользователи устанавливали приложения привычным для них способом. К этим форматам относятся msi и exe в Windows, pkg и dmg в macOS, deb и rpm в Linux.

  • Позволяет задавать параметры запуска на этапе упаковки.

  • Может вызываться напрямую из командной строки или программно через API ToolProvider.

Что не является целью

  • Следующие возможности устаревшего инструмента javapackager не поддерживаются:
    • поддержка приложений Java Web Start,
    • возможности, специфичные для JavaFX,
    • использование jdeps для определения необходимых модулей и
    • плагин для Ant.
  • Графического интерфейса у инструмента нет: достаточно интерфейса командной строки (CLI).

  • Кросс-компиляция не поддерживается. Например, чтобы создать пакеты для Windows, инструмент нужно запускать в Windows. Инструмент упаковки будет зависеть от платформенно-специфичных инструментов.

  • Особой поддержки юридических файлов, помимо той, что уже есть в файлах JMOD, нет. Объединения отдельных файлов лицензий не будет.

  • Нативная заставка при запуске (splash screen) не поддерживается.

  • Механизма автоматического обновления нет.

Мотивация

Многие Java-приложения нужно устанавливать на нативные платформы полноценно, а не просто помещать в путь к классам (class path) или путь к модулям (module path). Разработчику приложения недостаточно поставить простой JAR-файл: он должен поставить устанавливаемый пакет, подходящий для нативной платформы. Так Java-приложения можно распространять, устанавливать и удалять привычным для пользователей способом. Например, пользователи Windows ожидают, что смогут установить программу двойным щелчком по пакету, а затем удалить её через панель управления; пользователи macOS ожидают, что смогут дважды щёлкнуть по DMG-файлу и перетащить приложение в папку Application.

Инструмент jpackage также может помочь восполнить пробелы, оставшиеся после прежних технологий, таких как Java Web Start, удалённая из JDK 11 от Oracle, и pack200, удалённый в JDK 14 (JEP 367). Разработчики могут с помощью jlink урезать JDK до минимального набора необходимых модулей, а затем с помощью инструмента упаковки создать сжатый устанавливаемый образ, который можно развернуть на целевых машинах.

Раньше для решения этих задач вместе с JDK 8 от Oracle поставлялся инструмент упаковки javapackager. Однако он был удалён из JDK 11 от Oracle вместе с удалением JavaFX.

Описание

Инструмент jpackage упаковывает Java-приложение в платформенно-специфичный пакет, который включает все необходимые зависимости. Приложение может быть предоставлено как набор обычных JAR-файлов или как набор модулей. Поддерживаются следующие платформенно-специфичные форматы пакетов:

  • Linux: deb и rpm
  • macOS: pkg и dmg
  • Windows: msi и exe

По умолчанию jpackage создаёт пакет в формате, наиболее подходящем для системы, в которой он запущен.

Базовое использование: немодульные приложения

Предположим, у вас есть приложение из JAR-файлов, которые лежат в каталоге lib, и lib/main.jar содержит главный класс. Тогда команда

$ jpackage --name myapp --input lib --main-jar main.jar

упакует приложение в формате, используемом по умолчанию в локальной системе, и оставит итоговый файл пакета в текущем каталоге. Если в файле MANIFEST.MF в main.jar нет атрибута Main-Class, главный класс нужно указать явно:

$ jpackage --name myapp --input lib --main-jar main.jar \
  --main-class myapp.Main

Пакет будет называться myapp, хотя имя самого файла пакета будет длиннее и будет заканчиваться типом пакета (например, myapp.exe). Пакет будет включать лаунчер приложения, который тоже называется myapp. Чтобы запустить приложение, лаунчер поместит каждый JAR-файл, скопированный из входного каталога, в путь к классам JVM.

Если нужно создать пакет в формате, отличном от формата по умолчанию, используйте параметр --type. Например, чтобы создать в macOS файл pkg, а не dmg:

$ jpackage --name myapp --input lib --main-jar main.jar --type pkg

Базовое использование: модульные приложения

Если у вас модульное приложение, состоящее из модульных JAR-файлов и/или файлов JMOD в каталоге lib, а главный класс находится в модуле myapp, то команда

$ jpackage --name myapp --module-path lib -m myapp

упакует его. Если модуль myapp не указывает свой главный класс, его, опять же, нужно указать явно:

$ jpackage --name myapp --module-path lib -m myapp/myapp.Main

(При создании модульного JAR-файла или файла JMOD главный класс можно указать с помощью параметра --main-class инструментов jar и jmod.)

Метаданные пакета

Инструмент jpackage позволяет задавать различные платформенно-независимые метаданные, такие как имя и версия приложения (app-version), а также платформенно-специфичные метаданные для каждой платформы.

Описание всех параметров jpackage приведено на странице руководства (man page) jpackage.

Ассоциации файлов

Для приложения можно определить одну или несколько ассоциаций с типами файлов с помощью параметра --file-associations, который можно указывать несколько раз. Аргумент этого параметра — файл свойств со значениями для одного или нескольких из следующих ключей:

  • extension задаёт расширение файлов, которые будут связаны с приложением,
  • mime-type задаёт MIME-тип файлов, которые будут связаны с приложением,
  • icon задаёт значок внутри образа приложения, используемый для этой ассоциации, и
  • description задаёт краткое описание ассоциации.

Лаунчеры

По умолчанию инструмент jpackage создаёт для приложения простой нативный лаунчер. Лаунчер по умолчанию можно настроить с помощью следующих параметров:

  • --arguments <string> — аргументы командной строки, передаваемые главному классу, если лаунчеру не переданы аргументы командной строки (этот параметр можно указывать несколько раз)
  • --java-options <string> — параметры, передаваемые JVM (этот параметр можно указывать несколько раз)

Если приложению нужны дополнительные лаунчеры, их можно добавить с помощью параметра --add-launcher:

  • --add-launcher <launcher-name>=<file>

Указанный <file> должен быть файлом свойств со значениями для одного или нескольких ключей app-version icon arguments java-options main-class main-jar module или win-console. Значения этих ключей будут интерпретироваться как аргументы одноимённых параметров, но применительно к создаваемому лаунчеру, а не к лаунчеру по умолчанию. Параметр --add-launcher можно указывать несколько раз.

Образы приложений

Инструмент jpackage строит образ приложения, который служит входными данными для платформенно-специфичного инструмента упаковки, вызываемого на последнем шаге. Обычно этот образ является временным артефактом, но иногда его нужно настроить перед упаковкой. Поэтому инструмент jpackage можно запускать в два шага. Сначала создайте исходный образ приложения со специальным типом пакета app-image:

$ jpackage --name myapp --module-path lib -m myapp --type app-image

В результате в каталоге myapp будет создан образ приложения. Настройте этот образ так, как нужно, а затем создайте итоговый пакет с помощью параметра --app-image:

$ jpackage --name myapp --app-image myapp

Образы среды выполнения

Образ приложения содержит как файлы, из которых состоит ваше приложение, так и образ среды выполнения JDK, в котором будет работать приложение. По умолчанию инструмент jpackage вызывает инструмент jlink, чтобы создать образ среды выполнения. Содержимое образа зависит от типа приложения:

Набор параметров jlink, используемый jpackage по умолчанию:

--strip-native-commands --strip-debug --no-man-pages --no-header-files

но его можно изменить с помощью параметра --jlink-options. Итоговый образ не будет включать всех доступных поставщиков сервисов; если нужно их связать, используйте --jlink-options и включите --bind-services в список параметров jlink.

В обоих случаях, если в образ среды выполнения нужно включить дополнительные модули, можно использовать параметр --add-modules инструмента jpackage. Список модулей в образе среды выполнения приведён в файле release этого образа.

Образы среды выполнения, созданные инструментом jpackage, не содержат файла src.zip.

Если нужно дополнительно настроить образ среды выполнения, можно самостоятельно вызвать jlink и передать полученный образ инструменту jpackage через параметр --runtime-image. Например, если с помощью инструмента jdeps вы определили, что вашему немодульному приложению нужны только модули java.base и java.sql, размер пакета можно существенно уменьшить:

$ jlink --add-modules java.base,java.sql --output myjre
$ jpackage --name myapp --input lib --main-jar main.jar --runtime-image myjre

Структура и содержимое образа приложения

Структура и содержимое образов приложений зависят от платформы. Реальные образы содержат некоторые файлы, не показанные в приведённых ниже структурах; такие файлы являются деталями реализации и могут измениться в любой момент.

Linux

myapp/
  bin/              // Application launcher(s)
    myapp
  lib/
    app/
      myapp.cfg     // Configuration info, created by jpackage
      myapp.jar     // JAR files, copied from the --input directory
      mylib.jar
      ...
    runtime/        // JDK runtime image

Каталог установки по умолчанию в Linux — /opt. Его можно переопределить с помощью параметра --install-dir.

macOS

MyApp.app/
  Contents/
    Info.plist
    MacOS/          // Application launcher(s)
      MyApp
    Resources/      // Icons, etc.
    app/
      MyApp.cfg     // Configuration info, created by jpackage
      myapp.jar     // JAR files, copied from the --input directory
      mylib.jar
      ...
    runtime/        // JDK runtime image

Каталог установки по умолчанию в macOS — /Applications. Его можно переопределить с помощью параметра --install-dir.

Windows

MyApp/
  MyApp.exe         // Application launcher(s)
  app/
    MyApp.cfg       // Configuration info, created by jpackage
    myapp.jar       // JAR files, copied from the --input directory
    mylib.jar
    ...
  runtime/          // JDK runtime image

Каталог установки по умолчанию в Windows — C:\Program Files\. Его можно переопределить с помощью параметра --install-dir.

Поставка jpackage

Инструмент jpackage поставляется в составе JDK в модуле с именем jdk.jpackage.

Интерфейс командной строки соответствует JEP 293 (Guidelines for JDK Command-Line Tool Options).

Помимо интерфейса командной строки, jpackage доступен через ToolProvider API (java.util.spi.ToolProvider) под именем "jpackage".

Тестирование

Большинство тестов можно выполнять с помощью автоматизированных скриптов, но нужно учитывать несколько особенностей:

  • Для тестирования нативных пакетов может потребоваться установка дополнительных инструментов; такие тесты нужно будет писать так, чтобы они пропускались в системах, где нужных инструментов нет.

  • Проверка некоторых типов нативных пакетов (например, exe в Windows или dmg в macOS) может потребовать ручного тестирования.

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

Зависимости

Нативные пакеты создаются с помощью инструментов, доступных на хост-платформе. В Windows разработчикам нужно установить сторонний инструмент «Wix», чтобы создавать пакеты msi или exe.