Java 12 和 JavaFX 12 - 创建可运行的 jar 和自定义 JRE
Java 12 and JavaFX 12 - create runnable jar and custom JRE
我正在尝试使我的程序适应 运行 和 Java 12。它目前 运行s 与 Java 8 并且有一些 JavaFX组件(一些对话框)。它不是模块化的。我的 IDE 是 Eclipse,JavaFX jar 文件作为用户库包含在构建路径中。我想生成一个 运行nable jar 并将 javafx 文件捆绑在里面或将它们添加到自定义 JRE,这样我就可以分发它而无需最终用户拥有 Java12 或 JavaFX单独安装。
首先,我想尝试一个简单的 HelloFX 程序,修改后更接近我的程序。
public class HelloFX2 {
public HelloFX2() {
startToolkit();
// have to wait a second for the JavaFX thread to actually start, or else the Platform.runLater throws an exception
try
{
Thread.sleep(1000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
// create the scene and display
Platform.runLater(() -> {
Scene theScene = createTheScene();
final Stage stage = new Stage();
stage.setScene(theScene);
stage.show();
});
}
public Scene createTheScene() {
String javaVersion = System.getProperty("java.version");
String javafxVersion = System.getProperty("javafx.version");
Label l = new Label("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + ".");
Scene scene = new Scene(new StackPane(l), 640, 480);
return scene;
}
public void startToolkit () {
// we can only create a Scene in a JavaFX thread
SwingUtilities.invokeLater(() -> {
// Initialize FX Toolkit, so that we can use the Java FX objects
new JFXPanel();
});
}
}
我还根据 使用 Main class 到 运行。我不认为我需要它,因为 HelloFX2 没有扩展 Application
,但这又更接近我的实际程序的样子。
public class Main2 {
public static void main(String[] args) {
HelloFX2 theApp = new HelloFX2();
}
}
程序 运行 在 Eclipse 中运行良好。我使用 'Extract Libraries' 选项导出为 运行nable JAR 文件,然后使用 jdeps
和 jlink
创建自定义 JRE:
D:\Work\Java12>"C:\Program Files\Java\jdk-12.0.1\bin\jdeps" --ignore-missing-deps --print-module-deps HelloFX2.jar
java.base,java.desktop
D:\Work\Java12>"C:\Program Files\Java\jdk-12.0.1\bin\jlink" --no-header-files --no-man-pages --add-modules java.base,java.desktop --output java-runtime
但是当我尝试 运行 它时,我得到这个错误:
D:\Work\Java12>"java-runtime\bin\java" -jar HelloFX2.jar
Graphics Device initialization failed for : d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
at com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:243)
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:260)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.embed.swing.JFXPanel.lambda$initFx(JFXPanel.java:224)
at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
... 1 more
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: No toolkit found
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.embed.swing.JFXPanel.lambda$initFx(JFXPanel.java:224)
at java.base/java.lang.Thread.run(Thread.java:835)
当您不将 --module-path 开关添加到命令行时,这与原始 HelloFX 程序发生的错误相同,但我不需要它,因为我没有扩展 Application
.
没有找到JavaFX吗? JavaFX class 文件都包含在 jar 中,但我不确定如何指向它们。
使用 JavaFX SDK,有一个 lib
文件夹,其中包含 javafx.base.jar
或 javafx.controls.jar
等 jar,但也有 libglass.so
等本机库(Linux), libglass.dylib
(Mac).在 Windows 上,原生 dll,如 glass.dll
位于 bin
文件夹中。
将那些 类 打包到 fat jar 中时,您还必须考虑所需的本机库。
这意味着您必须为 javafx.graphics
打包本机库,但如果您不使用 javafx.web
模块。
另请注意,这些库是特定于平台的(甚至是 jars)。如果您想将 jar 分发到其他平台,您也可以从这些平台打包 类 和本机库,只需下载它们的 SDK。
所有这些都在 https://openjfx.io/openjfx-docs/#modular 部分 Non-modular 项目 - 命令行中进行了详细解释。
对于模块化项目,jlink
是推荐的工具。在这两种情况下,还使用构建工具 (Gradle/Maven) 确实有助于处理 JavaFX 依赖项:您不需要 JavaFX SDK,因为您将从 Maven Central 检索依赖项,并且这些已经将本机库与他们。同样,值得阅读整个 https://openjfx.io/openjfx-docs/#modular 文档。
我正在尝试使我的程序适应 运行 和 Java 12。它目前 运行s 与 Java 8 并且有一些 JavaFX组件(一些对话框)。它不是模块化的。我的 IDE 是 Eclipse,JavaFX jar 文件作为用户库包含在构建路径中。我想生成一个 运行nable jar 并将 javafx 文件捆绑在里面或将它们添加到自定义 JRE,这样我就可以分发它而无需最终用户拥有 Java12 或 JavaFX单独安装。
首先,我想尝试一个简单的 HelloFX 程序,修改后更接近我的程序。
public class HelloFX2 {
public HelloFX2() {
startToolkit();
// have to wait a second for the JavaFX thread to actually start, or else the Platform.runLater throws an exception
try
{
Thread.sleep(1000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
// create the scene and display
Platform.runLater(() -> {
Scene theScene = createTheScene();
final Stage stage = new Stage();
stage.setScene(theScene);
stage.show();
});
}
public Scene createTheScene() {
String javaVersion = System.getProperty("java.version");
String javafxVersion = System.getProperty("javafx.version");
Label l = new Label("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + ".");
Scene scene = new Scene(new StackPane(l), 640, 480);
return scene;
}
public void startToolkit () {
// we can only create a Scene in a JavaFX thread
SwingUtilities.invokeLater(() -> {
// Initialize FX Toolkit, so that we can use the Java FX objects
new JFXPanel();
});
}
}
我还根据 Application
,但这又更接近我的实际程序的样子。
public class Main2 {
public static void main(String[] args) {
HelloFX2 theApp = new HelloFX2();
}
}
程序 运行 在 Eclipse 中运行良好。我使用 'Extract Libraries' 选项导出为 运行nable JAR 文件,然后使用 jdeps
和 jlink
创建自定义 JRE:
D:\Work\Java12>"C:\Program Files\Java\jdk-12.0.1\bin\jdeps" --ignore-missing-deps --print-module-deps HelloFX2.jar
java.base,java.desktop
D:\Work\Java12>"C:\Program Files\Java\jdk-12.0.1\bin\jlink" --no-header-files --no-man-pages --add-modules java.base,java.desktop --output java-runtime
但是当我尝试 运行 它时,我得到这个错误:
D:\Work\Java12>"java-runtime\bin\java" -jar HelloFX2.jar
Graphics Device initialization failed for : d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
at com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:243)
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:260)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.embed.swing.JFXPanel.lambda$initFx(JFXPanel.java:224)
at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
... 1 more
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: No toolkit found
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.embed.swing.JFXPanel.lambda$initFx(JFXPanel.java:224)
at java.base/java.lang.Thread.run(Thread.java:835)
当您不将 --module-path 开关添加到命令行时,这与原始 HelloFX 程序发生的错误相同,但我不需要它,因为我没有扩展 Application
.
没有找到JavaFX吗? JavaFX class 文件都包含在 jar 中,但我不确定如何指向它们。
使用 JavaFX SDK,有一个 lib
文件夹,其中包含 javafx.base.jar
或 javafx.controls.jar
等 jar,但也有 libglass.so
等本机库(Linux), libglass.dylib
(Mac).在 Windows 上,原生 dll,如 glass.dll
位于 bin
文件夹中。
将那些 类 打包到 fat jar 中时,您还必须考虑所需的本机库。
这意味着您必须为 javafx.graphics
打包本机库,但如果您不使用 javafx.web
模块。
另请注意,这些库是特定于平台的(甚至是 jars)。如果您想将 jar 分发到其他平台,您也可以从这些平台打包 类 和本机库,只需下载它们的 SDK。
所有这些都在 https://openjfx.io/openjfx-docs/#modular 部分 Non-modular 项目 - 命令行中进行了详细解释。
对于模块化项目,jlink
是推荐的工具。在这两种情况下,还使用构建工具 (Gradle/Maven) 确实有助于处理 JavaFX 依赖项:您不需要 JavaFX SDK,因为您将从 Maven Central 检索依赖项,并且这些已经将本机库与他们。同样,值得阅读整个 https://openjfx.io/openjfx-docs/#modular 文档。