跳到主要内容

JEP 392:打包工具

概括

提供jpackage工具,用于打包独立的 Java 应用程序。

历史

该工具是由JEP 343jpackage作为 JDK 14 中的孵化工具引入的。它仍然是 JDK 15 中的孵化工具,以便有时间获得更多反馈。现在它已准备好从孵化升级为生产就绪功能。由于此转换,模块的名称将从 更改为。jpackage``jdk.incubator.jpackage``jdk.jpackage

相对于 JEP 343 的唯一实质性变化是我们将该--bind-services选项替换为更通用的--jlink-options选项,如下所述

目标

基于旧版 JavaFXjavapackager工具创建一个打包工具,该工具:

  • 支持原生打包格式,为最终用户提供自然的安装体验。这些格式包括Windows 上的msi和、macOS 上的 和Linux 上的和。exe``pkg``dmg``deb``rpm

  • 允许在打包时指定启动时参数。

  • 可以从命令行直接调用,也可以通过ToolProviderAPI 以编程方式调用。

非目标

  • javapackager不支持 旧版工具的以下功能:

    • Java Web Start 应用程序支持,
    • JavaFX 特定的功能,
    • jdeps用于确定所需模块的用途,以及
    • Ant 插件。
  • 该工具没有 GUI;命令行界面 (CLI) 就足够了。

  • 不支持交叉编译。例如,为了创建 Windows 软件包,必须在 Windows 上运行该工具。打包工具将取决于特定于平台的工具。

  • 除了 JMOD 文件中已提供的功能之外,没有对法律文件的特殊支持。不会有单个许可证文件的聚合。

  • 没有本机启动画面支持。

  • 没有自动更新机制。

动机

许多Java应用程序需要以一流的方式安装在本机平台上,而不是简单地放置在类路径或模块路径上。应用程序开发人员提供简单的 JAR 文件是不够的;他们必须提供适合本机平台的可安装包。这允许以用户熟悉的方式分发、安装和卸载 Java 应用程序。例如,在 Windows 上,用户希望能够双击软件包来安装其软件,然后使用控制面板删除该软件;在 macOS 上,用户希望能够双击 DMG 文件并将其应用程序拖到应用程序文件夹中。

jpackage 工具还可以帮助填补过去技术留下的空白,例如从 Oracle 的 JDK 11 中删除的 Java Web Start,以及在 JDK 14 ( JEP 367 )pack200中删除的 Java Web Start。开发人员可以将 JDK 剥离为所需的最小模块集,然后使用打包工具生成可部署到目标计算机的压缩的可安装映像。jlink

为了满足这些要求,之前随 Oracle 的 JDK 8 一起分发了一个名为 的打包工具。javapackager但是,作为删除 JavaFX 的一部分,它已从 Oracle 的 JDK 11 中删除。

描述

jpackage工具将 Java 应用程序打包到特定于平台的包中,其中包含所有必要的依赖项。应用程序可以作为普通 JAR 文件的集合或作为模块的集合来提供。支持的特定于平台的包格式有:

  • Linux:debrpm
  • macOS:pkgdmg
  • 窗户:msiexe

默认情况下,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文件而不是dmgmacOS 上的文件:

$ 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工具允许您指定各种独立于平台的元数据,例如名称和应用程序版本,以及每个平台的特定于平台的元数据。

所有 jpackage 选项的描述可以在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工具来创建运行时映像。图像的内容取决于应用程序的类型:

  • 对于由 JAR 文件组成的非模块化应用程序,运行时映像包含由常规启动器提供给未命名模块中的类路径应用程序java的同一组 JDK 模块。

  • 对于由模块化 JAR 文件和/或 JMOD 文件组成的模块化应用程序,运行时映像包含应用程序的主模块及其所有依赖项的传递闭包。

jlink使用的默认选项集jpackage

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

但这可以通过--jlink-options选项更改。生成的图像将不包括所有可用的服务提供商;如果您希望绑定它们,请使用--jlink-options并包含--bind-services在选项列表中jlink

在任何一种情况下,如果您希望将其他模块包含到运行时映像中,您可以使用该jpackage工具的--add-modules选项。运行时映像中的模块列表可在映像的发布文件中找到。

该工具创建的运行时映像jpackage不包含src.zip文件。

如果您希望进一步自定义运行时映像,则可以调用自己并通过选项jlink将生成的映像传递给工具。例如,如果您使用该工具确定您的非模块化应用程序仅需要和模块,则可以显着减小包的大小:jpackage``--runtime-imagejdepsjava.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选项覆盖。

苹果系统

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选项覆盖。

视窗

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(JDK 命令行工具选项指南)

除了命令行界面之外,jpackage还可以通过名称为 的ToolProvider API ( ) 进行访问。java.util.spi.ToolProvider``"jpackage"

测试

大多数测试可以使用自动化脚本完成,但有一些注意事项需要注意:

  • 测试本机包可能需要安装可选工具;需要编写这些测试,以便在没有必要工具的系统上跳过它们。

  • 验证某些类型的本机包(例如,exe在 Windows 或dmgmacOS 上)可能需要一些手动测试。

  • 我们需要确保原生包可以干净地安装和卸载,以便开发人员可以在本地环境中进行测试,而不必担心污染他们的系统。

依赖关系

本机包是使用主机平台上可用的工具生成的。在Windows上,开发者必须安装第三方“Wix”工具才能生成msiexe打包。