JEP 343:打包工具(孵化器)
概括
创建一个用于打包独立 Java 应用程序的工具。
目标
创建一个基于 JavaFXjavapackager
工具的简单打包工具,该工具:
-
支持原生打包格式,为最终用户提供自然的安装体验。这些格式包括Windows 上的
msi
和、macOS 上的 和Linux 上的和。exe``pkg``dmg``deb``rpm
-
允许在打包时指定启动时参数。
-
可以从命令行直接调用,也可以通过
ToolProvider
API 以编程方式调用。
非目标
- 该工具的以下功能
javapackager
将不受支持:- Java Web Start 应用程序支持,
- JavaFX 特定的功能,
jdeps
用于确定所需模块的用途,以及- Ant 插件。
- 该工具将没有 GUI;命令行界面 (CLI) 就足够了。
- 将不支持交叉编译。例如,为了创建 Windows 软件包,必须在 Windows 上运行该工具。打包工具将取决于特定于平台的工具。
- 除了 JMOD 文件中已提供的功能之外,不会对法律文件提供特殊支持。不会有单个许可证文件的聚合。
- 将没有本机启动画面支持。
- 不会有自动更新机制。
- 该工具在 Solaris 上不可用。
动机
许多Java应用程序需要以一流的方式安装在本机平台上,而不是简单地放置在类路径或模块路径上。应用程序开发人员提供简单的 JAR 文件是不够的;他们必须提供适合本机平台的可安装包。这允许以用户熟悉的方式分发、安装和卸载 Java 应用程序。例如,在 Windows 上,用户希望能够双击软件包来安装其软件,然后使用控制面板删除该软件;在 macOS 上,用户希望能够双击 DMG 文件并将其应用程序拖到应用程序文件夹中。
打包工具还可以帮助填补其他技术留下的空白,例如 Java Web Start(已从 Oracle 的 JDK 11 中删除)以及pack200
JDK 11 中已弃 用并在未来版本中删除的技术。开发人员可以jlink
将 JDK 剥离为所需的最小模块集,然后使用打包工具生成可部署到目标计算机的压缩的可安装映像。
为了满足这些要求,之前随 Oracle 的 JDK 8 一起分发了一个名为 的打包工具。javapackager
但是,作为删除 JavaFX 的一部分,它已从 Oracle 的 JDK 11 中删除。
描述
该jpackage
工具将 Java 应用程序打包到特定于平台的包中,其中包含所有必要的依赖项。应用程序可以作为普通 JAR 文件的集合或作为模块的集合来提供。支持的特定于平台的包格式有:
- Linux:
deb
和rpm
- macOS:
pkg
和dmg
- 窗户:
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
选项。例如,要生成pkg
文件而不是dmg
macOS 上的文件:
$ jpackage --name myapp --input lib --main-jar main.jar --type pkg
基本用法:模块化应用
如果您有一个模块化应用程序,由目录中的模块化 JAR 文件和/或 JMOD 文件组成lib
,并且主类位于 module 中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 <version>
--copyright <string>
--description <string>
--license-file <file>
--name <string>
--vendor <string>
该工具以适合包类型的方式使用为这些选项提供的参数。下面描述了特定于平台的包元数据选项。
文件关联
您可以通过该选项为您的应用程序定义一个或多个文件类型关联--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
工具来创建运行时映像。图像的内容取决于应用程序的类型:
-
对于由 JAR 文件组成的非模块化应用程序,运行时映像包含由常规启动器提供给未命名模块中的类路径应用程序
java
的同一组 JDK 模块。 -
对于由模块化 JAR 文件和/或 JMOD 文件组成的模块化应用程序,运行时映像包含应用程序的主模块及其所有依赖项的传递闭包。它不会包括所有可用的服务提供商;如果您希望绑定它们,请指定
--bind-services
该jpackage
工具的选项。
在任何一种情况下,如果您希望将其他模块添加到运行时映像中,您可以使用--add-modules
该工具的选项jpackage
。运行时映像中的模块列表可在映像release
文件中找到。
该工具创建的运行时映像jpackage
不包含调试符号、常用的 JDK 命令、手册页或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
特定于平台的详细信息
本节介绍该jpackage
工具的特定于平台的方面,包括应用程序映像布局和特定于平台的选项。该命令jpackage --help
将打印所有选项的摘要。
该工具创建的应用程序映像jpackage
包含一些在下面的布局中未显示的文件;此类文件应被视为可能会发生变化的实施细节。
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
选项覆盖。
Linux 特定选项:
--linux-package-name <package name>
— Linux 包的名称,默认为应用程序名称--linux-deb-maintainer <email address>
— DEB 包的维护者--linux-menu-group <menu-group-name>
— 此应用程序所在的菜单组--linux-package-deps <deps>
— 应用程序所需的包或功能--linux-rpm-license-type <type string>
— 许可证类型(License: <value>
RPM.spec
文件的)--linux-app-release <release value>
— RPM<name>.spec
文件的发行版值,或 DEB 控制文件的 Debian 修订版值--linux-app-category <category value>
— RPM<name>.spec
文件的 Group 值,或 DEB 控制文件的 Section 值--linux-shortcut
为应用程序创建快捷方式
苹果系统
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
选项覆盖。
macOS 特定选项:
--mac-package-identifier <string>
— 唯一标识 macOS 应用程序的标识符(默认为主类名称;仅限于字母数字、连字符和句点字符)--mac-package-name <string>
— 菜单栏中显示的应用程序名称(默认为应用程序名称;长度必须小于 16 个字符,并且适合在菜单栏和应用程序信息窗口中显示)--mac-package-signing-prefix <string>
— 对应用程序包进行签名时,该值会添加到需要签名但没有现有包标识符的所有组件之前--mac-sign
— 请求对捆绑包进行签名--mac-signing-keychain <file>
— 用于搜索签名身份的钥匙串路径(默认为标准钥匙串)--mac-signing-key-user-name <team name>
— Apple 签名身份的团队名称部分(例如“开发人员 ID 应用程序:”)
视窗
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
选项覆盖。
Windows 特定选项:
--win-console
— 为应用程序创建控制台启动器(应为需要控制台交互的应用程序指定)--win-dir-chooser
— 添加一个对话框,使用户能够选择安装应用程序的目录--win-menu
— 将应用程序添加到系统菜单--win-menu-group <menu-group-name>
— 放置此应用程序的“开始”菜单组--win-per-user-install
— 按用户安装应用程序--win-shortcut
— 为应用程序创建桌面快捷方式--win-upgrade-uuid <string>
— 与此包的升级相关的 UUID
交付jpackage
该工具将作为名为 的孵化器模块jpackage
在 JDK 中提供。作为孵化器模块中提供的功能,该工具的命令行选项、应用程序布局和其他导出接口不保证稳定,可能会在未来版本中进行修改。从命令行运行该工具时将显示警告。该模块默认不会被解析,并且在解析时会导致显示警告。jdk.incubator.jpackage``jpackage``jdk.incubator.jpackage
该jpackage
工具在该javapackager
工具的基础上,删除了与 Java Web Start 和 JavaFX 相关的所有功能。命令行界面 (CLI) 符合JEP 293(JDK 命令行工具选项指南)。除了命令行界面之外,jpackage
还可以通过名称为 的ToolProvider API ( ) 进行访问。java.util.spi.ToolProvider``"jpackage"
测试
大多数测试可以使用自动化脚本完成,但有一些注意事项需要注意:
-
测试本机包可能需要安装可选工具;需要编写这些测试,以便在没有必要工具的系统上跳过它们。
-
验证某些类型的本机包(例如,
exe
在 Windows 或dmg
macOS 上)可能需要一些手动测试。 -
我们需要确保原生包可以干净地安 装和卸载,以便开发人员可以在本地环境中进行测试,而不必担心污染他们的系统。
依赖关系
将使用目标平台上的工具生成本机包。对于 Windows,如果开发人员想要生成本机包,则需要安装一个附加工具:
msi
生成或exe
打包需要第三方工具Wix
目前正在努力增强jlink
在 JDK 未来版本中生成本机启动器的能力。jlink
和之间可能需要某种程度的协调jpackage
。