如何使用JRE部署JavaFX 11 Desktop应用程序

mcs*_*s75 21 java javafx openjfx javafx-11

我有一个JavaFX(JDK 8)桌面业务应用程序,它使用Java Web Start进行部署.用户安装了Java 8,他们只需转到URL(我的AWS Linux服务器上的公共URL),然后下载/启动应用程序(使用Web Start).我也可以通过将新JAR部署到服务器来轻松更新应用程序.一切都很好.

但是,Oracle已经停止了使用Java 11的Web Start,并且在2018年3月的"Java客户端路线图更新"白皮书中,他们建议将JRE与应用程序捆绑在一起("应用程序的概念是从独立的JRE单独分发的,因此,快速消退.").我不能依赖我的用户留在Java 8 for Web Start,即使他们仍然保持在8,Oracle也需要许可才能继续使用Java 8(我没有,可能非常昂贵,我更喜欢无论如何与社区一起走向JavaFX 11和OpenJDK).


我想迁移到JavaFX 11.我遵循OpenJFX的"JavaFX11入门"(https://openjfx.io/openjfx-docs/),使用OpenJDK 11.0.1和Gluon的JavaFX SDK 11.0.1(在Netbeans 10vc2上) ),并且已经能够运行示例应用程序(在我看来,我应该能够非常轻松地将我的JavaFX 8代码移植到JavaFX 11).

然而,这是我被困在方向的地方.如何将其与JRE捆绑在一起并将其部署到我的最终用户(并提供应用程序更新)?那里有一个简单的方法(甚至是艰难的方式,有一些方向/指南)?

我可以花几百个小时在JavaFX 11中编写富有表现力,丰富且有用的桌面业务应用程序,但我该怎么做呢?

部署工具包(如JWrapper,InstallAnywhere等)是否适合Java 11的这个新时代?Gluon/openjfx.io可能有我错过的推荐或指南吗?我似乎无法从信誉良好的来源找到任何建议或指南,因为我们开发人员如何专注于编写前端代码,以便部署应用程序.

感谢您的帮助或指导.

VGR*_*VGR 19

它现在的工作方式是,将程序转换为模块,然后将其"链接"到所需的所有其他模块.

这种链接过程的结果就是所谓的图像.图像实际上是一个文件树,其中包含一个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;
}
Run Code Online (Sandbox Code Playgroud)

建造

构建时,根本不指定类路径.而是指定模块路径.

模块路径是目录列表,而不是文件.每个目录都包含模块,这并不奇怪.jmods隐式包含JDK 的目录.您需要包含的只是包含所需的非JDK模块的目录.在你的情况下,这至少意味着Gluon的JavaFX:

javac -Xlint -g -d build/classes --module-path /opt/gluon-javafx/lib \
    src/java/com/mcs75/desktop/businessapp/*.java
Run Code Online (Sandbox Code Playgroud)

然后你通常的方式创建一个jar:

jar -c -f build/mybusinessapp.jar -C build/classes .
Run Code Online (Sandbox Code Playgroud)

其中包含module-info.class的jar文件被视为模块化jar.

制作一个jmod

创建jmod通常是一个简单的过程:

mkdir build/modules
jmod create --class-path build/mybusinessapp.jar \
    --main-class com.mcs75.desktop.businessapp.BuinessApplication \
    build/modules/mybusinessapp.jmod
Run Code Online (Sandbox Code Playgroud)

链接

最后,使用JDK的jlink命令组合所有内容:

jlink --output build/image \
    --module-path build/modules:/opt/gluon-javafx/lib \
    --add-modules com.mcs75.businessapp \
    --launcher MyBusinessApp=com.mcs75.businessapp
Run Code Online (Sandbox Code Playgroud)

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将拥有一个用于创建成熟的本机安装程序的打包工具.

跨楼宇

由于图像包含本机二进制文件,因此您需要为每个平台创建一个图像.显然,一种选择是在Linux系统上构建映像,再在Windows系统上构建映像,再在Mac上构建映像等.

但您也可以使用jmodjlink为其他平台创建图像,无论您在哪里构建.

只需要几个额外的步骤.首先,您将需要其他平台的JDK.将它们下载为档案(zip或tar.gz),而不是安装程序,并将它们解压缩到您选择的目录中.

每个JDK定义一个平台字符串.这通常是<os> - <arch>的形式.该平台是该java.base模块的一个属性; 您可以通过检查该模块来查看任何JDK的平台:

jmod describe path-to-foreign-jdk/jmods/java.base.jmod | grep '^platform'
Run Code Online (Sandbox Code Playgroud)

使用以下--target-platform选项将该平台字符串传递给您的jmod命令:

mkdir build/modules
jmod create --target-platform windows-amd64 \
    --class-path build/mybusinessapp.jar \
    --main-class com.mcs75.desktop.businessapp.BuinessApplication \
    build/modules/mybusinessapp.jmod
Run Code Online (Sandbox Code Playgroud)

最后,在链接时,您希望显式包含其他JDK的jmods目录,因此jlink不会隐式包含其自己的JDK模块:

jlink --output build/image \
    --module-path path-to-foreign-jdk/jmods:build/modules:/opt/gluon-javafx/lib \
    --add-modules com.mcs75.businessapp \
    --launcher MyBusinessApp=com.mcs75.businessapp
Run Code Online (Sandbox Code Playgroud)

  • 截至2018年12月1日,这里发布了更多信息:https://medium.com/@adam_carroll/java-packager-with-jdk11-31b3d620f4a8 (2认同)
  • 您如何最好地将这些步骤集成到 Maven 中? (2认同)