它现在的工作方式是将程序转换为模块,然后将其“链接”到它需要的所有其他模块。
这个链接过程的结果就是所谓的图像。映像实际上是一棵文件树,其中包括一个bin
目录,其中包含一个或多个可立即运行的可执行文件。这棵树就是您分发的内容,通常以 zip 或 tar.gz 的形式分发。
步骤是:
- 创建一个 module-info.java
- 使用模块路径而不是类路径编译
- 像往常一样从类创建一个 jar
jmod
使用 JDK 的工具将 jar 转换为 jmod
- 将该 jmod 及其所依赖的模块链接到图像中
编写模块描述符
第一步是将应用程序变成一个模块。最低限度,这需要module-info.java
在源代码树的顶部(即在空包中)创建一个。每个模块都有一个名称,通常与包名称相同,但并非必须如此。因此,您的 module-info.java 可能如下所示:
module com.mcs75.businessapp {
exports com.mcs75.desktop.businessapp;
requires java.logging;
requires transitive javafx.graphics;
requires transitive javafx.controls;
}
建造
构建时,您根本不指定类路径。相反,您指定一个模块路径。
模块路径是目录列表,而不是文件。毫不奇怪,每个目录都包含模块。JDK的jmods
目录是隐含的。您需要包含的只是包含您需要的非 JDK 模块的目录。在您的情况下,这至少意味着 Gluon 的 JavaFX:
javac -Xlint -g -d build/classes --module-path /opt/gluon-javafx/lib \
src/java/com/mcs75/desktop/businessapp/*.java
然后以通常的方式创建一个 jar:
jar -c -f build/mybusinessapp.jar -C build/classes .
包含 module-info.class 的 jar 文件被视为模块化 jar。
制作一个jmod
创建 jmod 通常是一个简单的过程:
mkdir build/modules
jmod create --class-path build/mybusinessapp.jar \
--main-class com.mcs75.desktop.businessapp.BusinessApplication \
build/modules/mybusinessapp.jmod
链接
最后,您使用 JDK 的jlink
命令来组装所有内容:
jlink --output build/image \
--module-path build/modules:/opt/gluon-javafx/lib \
--add-modules com.mcs75.businessapp \
--launcher MyBusinessApp=com.mcs75.businessapp
jlink
创建一个最小的 JRE,其中仅包含您显式添加的模块(以及那些显式模块需要的模块)。 --add-modules
是指定要添加的内容的必需选项。
与其他 JDK 工具一样,--module-path
指定包含模块的目录。
该选项会导致最终图像树在其目录中具有给定名称(等号之前的部分)--launcher
的附加可执行脚本。bin
所以,MyBusinessApp=com.mcs75.businessapp
意思是“创建一个名为 MyBusinessApp 的可执行文件,它执行模块 com.mcs75.businessapp。”</p>
因为该jmod create
命令包含一个--main-class
选项,Java 将知道要执行什么,就像在清单中声明 Main-Class 属性一样。如果需要,也可以在--launcher
选项中显式声明要执行的类。
分发
您将要分发的是整个图像文件树的 zip 或 tar.gz。用户应该运行的可执行文件位于图像的bin
目录中。当然,您可以自由添加自己的可执行文件。只要保留图像树的结构,您也可以自由地将其放入任何类型的安装程序中。
未来的 JDK 将有一个用于创建成熟的本地安装程序的打包工具。 从 Java 14 开始,JDK 有一个jpackage工具,可以创建本机安装程序。例如:
jpackage -n MyBusinessApp --runtime-image build/image \
-m com.mcs75.businessapp/com.mcs75.desktop.businessapp.BusinessApplication
-n
指定程序的名称。 --runtime-image
指定现有 jlink'd 图像的位置。 -m
是 jlink'd 映像中要执行的模块和类,很像 in jlink 选项之后的=
部分--launcher
。
交叉建设
由于映像包含本机二进制文件,因此您需要为每个平台创建一个映像。显然,一种选择是在 Linux 系统上构建映像,然后在 Windows 系统上构建映像,然后在 Mac 上构建,等等。
但是,无论您在哪里构建,您也可以使用jmod
和创建其他平台的图像。jlink
只需要几个额外的步骤。首先,您将需要其他平台的 JDK。将它们下载为档案(zip 或 tar.gz),而不是安装程序,然后将它们解压到您选择的目录中。
每个 JDK 都定义了一个平台字符串。这通常是 <os>-<arch> 的形式。平台是java.base
模块的属性;通过检查该模块,您可以看到任何 JDK 的平台:
jmod describe path-to-foreign-jdk/jmods/java.base.jmod | grep '^platform'
使用以下选项将该平台字符串传递给您的 jmod 命令--target-platform
:
mkdir build/modules
jmod create --target-platform windows-amd64 \
--class-path build/mybusinessapp.jar \
--main-class com.mcs75.desktop.businessapp.BusinessApplication \
build/modules/mybusinessapp.jmod
最后,在链接时,您希望显式包含其他 JDK 的jmods
目录,因此 jlink 不会隐式包含自己的 JDK 模块:
jlink --output build/image \
--module-path path-to-foreign-jdk/jmods:build/modules:/opt/gluon-javafx-windows/lib \
--add-modules com.mcs75.businessapp \
--launcher MyBusinessApp=com.mcs75.businessapp