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

标签 java javafx javafx-11 openjfx

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

但是,Oracle已停止使用Java 11进行Web Start,并且在2018年3月的“Java客户端路线图更新”白皮书中,他们建议将JRE与应用程序 bundle 在一起(“应用程序与独立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 bundle 在一起并将其部署到最终用户(并提供应用程序更新)?有没有简单的出路(甚至有一些方向/指南的艰难出路)?

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

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

感谢您的帮助或指导。

最佳答案

现在它的工作方式是,将程序转换为模块,然后将其“链接”到其所需的所有其他模块。
链接过程的结果就是所谓的图像。镜像实际上是文件树,其中包括带有一个或多个现成可执行文件的bin目录。这棵树是您分发的,通常是zip或tar.gz。
这些步骤是:

  • 创建一个模块信息.java
  • 使用模块路径而不是类路径进行编译
  • 像往常一样从类中创建一个jar
  • 使用JDK的jmod工具
  • 将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;
    }
    
    build
    构建时,您根本不需要指定类路径。而是指定模块路径。
    模块路径是目录列表,而不是文件列表。毫不奇怪,每个目录都包含模块。 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将知道要执行的内容,就像在 list 中声明Main-Class属性一样。如果需要,还可以在--launcher选项中显式声明要执行的类。
    分布
    您将要分发的是整个图像文件树的zip或tar.gz。用户应运行的可执行文件位于图像的bin目录中。当然,您可以自由添加自己的可执行文件。只要保留图像树的结构,您还可以将其随意放置在任何类型的安装程序中。
    将来的JDK将具有packaging tool,用于创建完整的 native 安装程序。从Java 14开始,JDK具有jpackage工具,可以创建 native 安装程序。例如:
    jpackage -n MyBusinessApp --runtime-image build/image \
        -m com.mcs75.businessapp/com.mcs75.desktop.businessapp.BusinessApplication
    
    -n指定程序的名称。 --runtime-image指定现有jlink图片的位置。 -m是要执行的jlink图片中的模块和类,就像jlink的=选项中--launcher之后的部分一样。
    交叉 build
    由于该镜像包含 native 二进制文件,因此您需要为每个平台创建一个镜像。显然,一种选择是在Linux系统上,在Windows系统上,再在Mac等上构建镜像。
    但是,无论您在哪里 build ,都可以使用jmodjlink为其他平台创建图像。
    只需几个额外的步骤。首先,您将需要用于其他平台的JDK。将它们下载为存档文件(zip或tar.gz),而不是安装程序,然后将其解压缩到您选择的目录中。
    每个JDK都定义一个平台字符串。通常采用-的形式。该平台是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
    

    关于java - 如何使用JRE部署JavaFX 11 Desktop应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53453212/

    相关文章:

    java - 我如何在 JRuby 中加载已编译的 Java 类?

    java - 为 HBox 设置背景图像 - JavaFX

    java - 如何将方法 StageHelper.getStages() 从 java 1.7 替换为 java 11

    javafx - 带有 JavaFx 11 和 JDK 11 的 Netbeans 9.0

    java - 多个 'Extends'

    java - 获取集合中 N 个最小的 [Comparable] 项

    java - 子类参数化问题

    java - 如何在 IDE 之外启动 JavaFX 11 应用程序?

    java - 为什么会发生 "Could not locate ordinal parameter [0], expecting one of []"?

    java - 如何将 JavaFX slider 绑定(bind)到显示列表中的值的标签?