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

时间:2018-11-23 21:40:29

标签: java javafx javafx-11 openjfx

我有一个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进行Web Start,即使他们保持在8岁,Oracle也要求获得许可证才能继续使用Java 8(我没有,但是价格很高,我更喜欢无论如何都要与社区一起向JavaFX 11和OpenJDK迁移。

我想迁移到JavaFX11。我已经将OpenJDK 11.0.1与Gluon的JavaFX SDK 11.0.1(在Netbeans 10vc2上)一起使用,遵循了OpenJFX的“ JavaFX11入门”(https://openjfx.io/openjfx-docs/)。能够运行示例应用程序(在我看来,我应该可以很容易地将JavaFX 8代码移植到JavaFX 11)。

但是,这是我坚持寻求指导的地方。如何将其与JRE捆绑在一起并将其部署到最终用户(并提供应用程序更新)?有没有简单的出路(甚至有一些方向/指南的艰难出路)?

我可以花数百小时​​来用JavaFX 11编写富有表现力,功能丰富且有用的桌面业务应用程序,但是我该怎么办?

JWrapper,InstallAnywhere等部署工具包是否适合Java 11的新时代? Gluon / openjfx.io可能有我错过的推荐或指南吗?我似乎找不到可靠来源的任何建议或指南,因为专注于编写前端代码的美国开发人员将如何部署应用程序。

感谢您的帮助或指导。

4 个答案:

答案 0 :(得分:12)

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

此链接过程的结果就是所谓的图像。映像实际上是文件树,它包含一个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.BuinessApplication \
    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将具有packaging tool,用于创建完整的本机安装程序。

交叉建筑

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

但是您也可以使用jmodjlink来为其他平台创建图像,无论您在何处进行构建。

仅需执行几个其他步骤。首先,您将需要用于其他平台的JDK。将其下载为归档文件(zip或tar.gz)而不是安装程序,然后将其解压缩到您选择的目录中。

每个JDK定义一个 platform 字符串。通常采用-的形式。该平台是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.BuinessApplication \
    build/modules/mybusinessapp.jmod

最后,在链接时,您希望显式包括其他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

答案 1 :(得分:0)

José:我看到我们要解决相同的问题(请参见Self-Contained Application Packaging for a JavaFX app on Windows: InnoSetup OR javafxpackager?的问题)。尽管有许多参数,使用JDK的javapackager也许是一个“简单”的解决方案。就我而言,我是否已通过此工具成功生成了“ Windows上JavaFX应用程序的自包含应用程序打包”?

答案 2 :(得分:0)

为了使用IDE使事情变得更容易,我使用了Intellij Idea。构建自动化,我使用gradle;和jlink插件,我使用badass Jlink插件-https://badass-jlink-plugin.beryx.org/releases/latest/#jpackageImage。然后,您可以轻松使用jlink和jpackage。只是一个想法。

答案 3 :(得分:-1)

尝试install4j。这可能是您的救星。

查看本文以了解其他开发人员的痛苦:

https://voyagergames.com/distributing-a-desktop-java-application/