现在的工作方式是,将程序转换为模块,然后“链接”它到所有其他所需的模块。
这个链接过程的结果被称为一个镜像。镜像实际上是一个文件树,其中包括一个带有一个或多个可运行可执行文件的bin目录。这个树是你通常会分发的,比如zip或tar.gz。
步骤如下:
1. 创建一个module-info.java
2. 使用模块路径而不是类路径进行编译
3. 像往常一样从类创建jar
4. 使用JDK的jmod工具将jar转换为jmod
5. 将该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。”
由于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映像中要执行的模块和类,类似于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'
使用--target-platform
选项将该平台字符串传递给您的jmod命令:
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
jlink
创建运行时映像。但对于社区来说,你需要一步步进行发布并提供解决方案。 - Naman