如何使用 JRE 部署 JavaFX 11 桌面应用程序 [英] How to deploy a JavaFX 11 Desktop application with a JRE

查看:48
本文介绍了如何使用 JRE 部署 JavaFX 11 桌面应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JavaFX (JDK 8) desktop business application, which uses Java Web Start for deployment. Users have Java 8 installed, and they simply go to the URL (a public URL on my AWS Linux server) and the application downloads / starts (using Web Start). I can easily update the application, too, by deploying new JARs to the server. Everything works well.

但是,Oracle 已经停止使用 Java 11 的 Web Start,并且在 2018 年 3 月的Java 客户端路线图更新"白皮书中,他们建议将 JRE 与应用程序捆绑在一起(应用程序与独立应用程序分开分发的概念因此,JRE 正在迅速消失.").我不能指望我的用户在 Web Start 上一直使用 Java 8,即使他们仍然使用 Java 8,Oracle 也需要获得许可才能继续使用 Java 8(我没有,这可能非常昂贵,我更喜欢无论如何,与社区一起向 JavaFX 11 和 OpenJDK 迈进).

However, Oracle has discontinued Web Start with Java 11, and in their "Java Client Roadmap Update" white paper, March 2018, they recommend bundling a JRE with the application ("The notion of an application being distributed separately from a standalone JRE is, therefore, quickly fading."). I cannot rely on my users to stay at Java 8 for Web Start, and even if they do remain at 8, Oracle requires a license to continue using Java 8 (which I do not have, can be very costly, and I’d prefer anyways to move with the community towards JavaFX 11 and 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.


I would like to migrate to JavaFX 11. I have followed OpenJFX’s "Getting Started with JavaFX11" (https://openjfx.io/openjfx-docs/), using OpenJDK 11.0.1 with Gluon’s JavaFX SDK 11.0.1 (on Netbeans 10vc2), and have been able to get the sample applications to run (and appears to me I should be able to port my JavaFX 8 code to JavaFX 11, quite easily).

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

However, this is where I am stuck for direction. How do I bundle this with the JRE and deploy this to my end-users (and provide application updates)? Is there an easy way out there (or even a hard way, with some direction/guides)?

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

I can spend hundreds of hours writing expressive, rich, and useful desktop business applications in JavaFX 11, but what do I do then?

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

Are the deployment toolkits, like JWrapper, InstallAnywhere, etc, suited to this new era of Java 11? Does Gluon/openjfx.io perhaps have a recommendation or guide I missed? I cannot seem to find any recommendations or guides from reputable sources, for how us developers, who focus on writing the front-end code, are to deploy the applications.

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

Thank you for any help or guidance.

推荐答案

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

The way it works now is, you convert your program to a module, then "link" it to all the other modules it requires.

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

The result of this linking process is what’s known as an image. An image is actually a file tree, which includes a bin directory with one or more ready-to-run executables. This tree is what you distribute, typically as a zip or tar.gz.

步骤是:

  1. 创建一个module-info.java
  2. 使用模块路径而不是类路径进行编译
  3. 像往常一样从类创建一个 jar
  4. 使用 JDK 的 jmod 工具将 jar 转换为 jmod
  5. 将该 jmod 及其所依赖的模块链接到一个图像中
  1. Create a module-info.java
  2. Compile with a module path instead of a classpath
  3. Create a jar from classes, as usual
  4. Convert jar to a jmod with the JDK’s jmod tool
  5. Link that jmod, and the modules on which it depends, into an image

编写模块描述符

第一步是将应用程序变成一个模块.至少,这需要在源代码树的顶部(即在空包中)创建一个 module-info.java.每个模块都有一个名称,该名称通常与包名称相同,但并非必须如此.因此,您的 module-info.java 可能如下所示:

Writing a module descriptor

The first step is to turn the application into a module. Minimally, this requires creating a module-info.java at the top of your source tree (that is, in the empty package). Every module has a name, which is often the same as a package name but doesn’t have to be. So, your module-info.java might look like this:

module com.mcs75.businessapp {
    exports com.mcs75.desktop.businessapp;

    requires java.logging;
    requires transitive javafx.graphics;
    requires transitive javafx.controls;
}

建筑

在构建时,根本不指定类路径.相反,您指定一个模块路径.

Building

When you build, you don’t specify a classpath at all. Instead, you specify a module path.

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

A module path is a list of directories, not files. Each directory contains, not surprisingly, modules. The jmods directory of the JDK is included implicitly. All you need to include is directories containing the non-JDK modules you need. In your case, that at least means Gluon’s JavaFX:

javac -Xlint -g -d build/classes --module-path /opt/gluon-javafx/lib 
    src/java/com/mcs75/desktop/businessapp/*.java

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

Then you create a jar the usual way:

jar -c -f build/mybusinessapp.jar -C build/classes .

包含 module-info.class 的 jar 文件被认为是模块化 jar.

A jar file with a module-info.class in it is considered a modular jar.

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

Creating a jmod is usually a simple process:

mkdir build/modules
jmod create --class-path build/mybusinessapp.jar 
    --main-class com.mcs75.desktop.businessapp.BusinessApplication 
    build/modules/mybusinessapp.jmod

链接

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

Linking

Finally, you use the JDK’s jlink command to assemble everything:

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 是指定要添加的内容的必需选项.

jlink creates a minimal JRE, which contains only the modules you explicitly add (and the modules those explicit modules require). --add-modules is the required option that specifies what to add.

与其他 JDK 工具一样,--module-path 指定包含模块的目录.

As with other JDK tools, --module-path specifies directories containing modules.

--launcher 选项使最终的图像树在其 bin 目录中有一个附加的可执行脚本,具有给定的名称(等号之前的部分).所以,MyBusinessApp=com.mcs75.businessapp 的意思是创建一个名为 MyBusinessApp 的可执行文件,它执行模块 com.mcs75.businessapp."

The --launcher option causes the final image tree to have an additional executable script in its bin directory with the given name (the part before the equals). So, MyBusinessApp=com.mcs75.businessapp means "create an executable named MyBusinessApp, which executes the module com.mcs75.businessapp."

因为 jmod create 命令包含一个 --main-class 选项,Java 将知道要执行什么,就像在清单中声明 Main-Class 属性一样.如果需要,也可以在 --launcher 选项中显式声明要执行的类.

Because the jmod create command included a --main-class option, Java will know what to execute, just like declaring a Main-Class attribute in a manifest. It is also possible to explicitly declare a class to execute in the --launcher option if desired.

您要分发的是整个图像文件树的 zip 或 tar.gz.用户应该运行的可执行文件位于图像的 bin 目录中.当然,您可以自由添加自己的可执行文件.您也可以随意将其放入任何类型的安装程序中,只要保留图像树的结构即可.

What you will want to distribute is a zip or tar.gz of the entire image file tree. The executable that the user should run is in the image’s bin directory. Of course, you are free to add your own executables. You are also free to place this into any kind of installer, as long as the image tree’s structure is preserved.

未来的 JDK 将有一个 打包工具,用于创建成熟的本地安装程序. 从 Java 14 开始,JDK 有一个 jpackage 工具,可以创建本机安装程序.例如:

A future JDK will have a packaging tool for creating full-fledged native installers. As of Java 14, the JDK has a jpackage tool which can create native installers. For example:

jpackage -n MyBusinessApp --runtime-image build/image 
    -m com.mcs75.businessapp/com.mcs75.desktop.businessapp.BusinessApplication

-n 指定程序的名称.--runtime-image 指定现有 jlink 图像的位置.-m 是 jlink 图像中要执行的模块和类,很像 jlink 的 --launcher 选项中 = 之后的部分.

-n specifies the name of the program. --runtime-image specifies the location of the existing jlink’d image. -m is the module and class within the jlink’d image to execute, much like the portion after the = in jlink’s --launcher option.

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

Since the image includes native binaries, you will need to create an image for each platform. Obviously, one option is to build the image on a Linux system, and again on a Windows system, and again on a Mac, etc.

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

But you can also use jmod and jlink to create images for other platforms, regardless of where you’re building.

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

There’s only a few additional steps needed. First, you will need the JDKs for those other platforms. Download them as archives (zip or tar.gz), not installers, and unpack them to directories of your choice.

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

Each JDK defines a platform string. This is normally of the form <os>-<arch>. The platform is a property of the java.base module; you can see any JDK’s platform by examining that module:

jmod describe path-to-foreign-jdk/jmods/java.base.jmod | grep '^platform'

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

Pass that platform string to your jmod command using the --target-platform option:

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 模块:

Finally, when linking, you want to explicitly include the other JDK’s jmods directory, so jlink won’t implicitly include its own JDK’s modules:

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

这篇关于如何使用 JRE 部署 JavaFX 11 桌面应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆