当前位置: 首页 > 知识库问答 >
问题:

如何使用JRE部署JavaFX11桌面应用程序

百里锋
2023-03-14

我想迁移到JavaFX11。我已经学习了OpenJFX的“JavaFX11入门”(https://openjfx.io/openjfx-docs/),使用OpenJDK 11.0.1和Gluon的JavaFX SDK 11.0.1(在Netbeans 10VC2上),并且已经能够使示例应用程序运行(在我看来,我应该能够很容易地将JavaFX8代码移植到JavaFX11)。

然而,这正是我无法找到方向的地方。我如何将它与JRE捆绑在一起,并将其部署到最终用户(并提供应用程序更新)?有没有一条简单的路(或者甚至是一条艰难的路,有一些方向/向导)?

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

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

感谢您的任何帮助或指导。

共有1个答案

夹谷腾
2023-03-14

它现在的工作方式是,你把你的程序转换成一个模块,然后把它“链接”到它所需要的所有其他模块。

这个链接过程的结果就是所谓的图像。映像实际上是一个文件树,它包括一个bin目录,其中包含一个或多个准备运行的可执行文件。这棵树是您分发的,通常是zip或tar.gz。

这些步骤是:

    null
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 .
mkdir build/modules
jmod create --class-path build/mybusinessapp.jar \
    --main-class com.mcs75.desktop.businessapp.BusinessApplication \
    build/modules/mybusinessapp.jmod
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。”

您将希望分发的是整个图像文件树的一个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映像的位置。-m是JLink的映像中要执行的模块和类,与JLink的--launcher选项中=后面的部分非常相似。

但是您也可以使用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
 类似资料:
  • 使用JDeveloper 12.1.3.0.0,我创建了一个Java桌面应用程序,它使用Oracle JDBC和BC4J Oracle域库(通过项目属性->库和类路径添加它们)。在JDeveloper中,所有的东西都可以很好地编译和运行,但是我很难部署一个工作的JAR文件。这个JAR文件需要包含库,因为它将直接放置到客户端机器上。 当前失败得尝试:我已在项目属性中创建了部署配置文件.这个概要文件将

  • 我正在研究Terraform以及如何使用它来设置AWS环境。到目前为止,我已经有了用3个公共子网、3个私有子网、一个互联网网关和3个Nat网关设置VPC的脚本。然而,我对如何在私有子网中部署和重新部署应用程序感到困惑? 在我的场景中,我们使用Spring Boot构建微服务。我们的想法是转移到一种状态,在这种状态下,我们可以将弹性负载平衡器连接到公共子网,并在私有子网中的自动缩放组中承载我们的应用

  • 我有一个小型Java桌面应用程序,没有任何图形用户界面。我使用蚂蚁来开发、运行、构建和发布它。我没有为它创建一个jar文件。我使用一个. sh文件来启动/运行它,并在发行版中附加JRE。 现在我在上面添加了一个简单的JavaFX2GUI。我仍然可以用Ant开发、运行、构建和发布。JavaFX的Ant文件中没有特殊的目标或添加。发布后,我无法再使用现有的.sh文件运行它。我收到以下错误: 线程"ma

  • 在学习这本书的过程中,你已经掌握了很多关于 Git 的命令。虽然这些是在学习过程中不可缺少的,但是版本控制的核心并不是让你学习所有的命令和参数。 当你掌握一些基本的概念,再加上一个带有用户图形界面的应用程序的帮助,就可以让你的日常工作变得更加简单。一个最大的好处就是它会为你提供了一个可视化的用户操作界面。 在桌面应用程序中,很多任务使用起来会更加容易和更方便。并且你也不需要记住那几十个繁琐的 Gi

  • 问题内容: 首先,我对专业从事这项工作不感兴趣。我是一名Web开发人员,我的一个同事最近离开了Spotify,他说他将主要在JavaScript中使用SpotifyDesktop应用程序。他说,它使用“ Chrome框架”,并且内部的所有内容都像网络应用程序(HTML / JS / CSS)一样完成。 作为一个从未为Desktop构建任何东西的Web开发人员,这是个好消息。如果我可以使用我已经知道

  • 问题内容: JAX-RS 1.1规范在第6页上说: 如果不存在Application子类,则必须将添加的servlet命名为: 添加的servlet是什么?可以是任意servlet吗? 如果存在Application子类,并且已经定义了一个servlet,该servlet的servlet初始化参数为: 同样,这里的“ servlet”是什么? 如果存在不由现有Servlet处理的Applicati