使用 JavaFX 11 的自定义 JRE
Custom JRE with JavaFX 11
我正在使用 JDK11 和 JavaFX11。
我使用 Jlink 为我的示例 FX 模块程序创建了自定义 JRE,但是当我尝试 运行 使用自定义 JRE 时,它呈现如下错误:
这就是我创建自定义 JRE 的方式(没有错误):
jlink --module-path ..\jmods;%PATH_TO_FX% --add-modules java.base,java.desktop,jdk.unsupported,javafx.graphics --output FXJRE
这就是我尝试 运行(有错误)的方式:
FXJRE\bin\java --module-path %PATH_TO_FX%;mods -m com.javafxdemo/com.javafxdemo.JavaFXDemo
错误信息:
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 javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:222)
at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:260)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:409)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
at java.base/java.lang.Thread.run(Thread.java:834)
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: No toolkit found
at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:409)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
... 5 more
以下是我的编译方式:
来源JavaFXDemo.java:
package com.javafxdemo;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class JavaFXDemo extends Application {
@Override
public void start(Stage stage) {
stage.setTitle("Hello World");
Group root = new Group();
Scene scene = new Scene(root, 300, 250);
Button btn = new Button();
btn.setLayoutX(100);
btn.setLayoutY(80);
btn.setText("Hello World");
btn.setOnAction(actionEvent -> System.out.println("Hello World"));
root.getChildren().add(btn);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
module-info.java
:
module com.javafxdemo {
requires javafx.base;
requires javafx.graphics;
requires javafx.controls;
exports com.javafxdemo;
}
我是这样编译的。
javac -d mods\com.javafxdemo --module-path %PATH_TO_FX% src\com.javafxdemo\module-info.java src\com.javafxdemo\com\javafxdemo\JavaFXDemo.java
编译后,我有如下模块 class 个文件:
├───mods
│ └───com.javafxdemo
│ │ module-info.class
│ │
│ └───com
│ └───javafxdemo
│ JavaFXDemo.class
│
└───src
└───com.javafxdemo
│ module-info.java
│
└───com
└───javafxdemo
JavaFXDemo.java
我可以成功 运行 如下:
java --module-path %PATH_TO_FX%;mods -m com.javafxdemo/com.javafxdemo.JavaFXDemo
不过我可以 运行 使用默认的 JDK11。
如何成功创建自定义 JRE 和 运行 示例 FX 模块程序?
如果您转到此 link,您会注意到每个平台的 JavaFX 发行版有两种风格:
JavaFX SDK 是您正在使用的那个:
export PATH_TO_FX=/path/to/javafx-sdk-11/lib
如果您检查 lib
下的文件,这些是 jar。
另一边的 JavaFX jmods 包含 jmod 格式。
如果您了解 jmod
格式 here:
For most development tasks, including deploying modules on the module path or publishing them to a Maven repository, continue to package modules in modular JAR files. The jmod tool is intended for modules that have native libraries or other configuration files or for modules that you intend to link, with the jlink tool, to a runtime image.
换句话说,如果您使用 javac
或 java
来 运行 您的 jar 或模块,您可以使用 SDK,但如果您使用 jlink
来创建自定义 JRE,您需要 jmod
版本。
一旦你下载了 jmods,解压它们并创建这个变量:
export PATH_TO_FX_JMOD=/path/to/javafx-jmods-11/
现在您可以创建 JRE:
jlink --module-path %PATH_TO_FX_JMOD%;mods --add-modules=com.javafxdemo --output FXJRE
和运行:
FXJRE/bin/java -m com.javafxdemo/com.javafxdemo.JavaFXDemo
Ubuntu18.04,Java11,Netbeans 11.0:
我遇到了与您相同的错误,因为我使用 /usr/share/openjfx/lib 中来自 Ubuntu openjfx 11.0.2+1-1~18.04.2 包的 jars 设置了库 JavaFX11。我想因为这个目录中有相同的 jars 我可以使用它但是你通过从 https://gluonhq.com/products/javafx/ 下载 JavaFX Linux SDK 获得的 javafx-sdk-11.0.2/lib 目录包含很多其他需要的库文件(如 libglass.so)。
我正在使用 JDK11 和 JavaFX11。
我使用 Jlink 为我的示例 FX 模块程序创建了自定义 JRE,但是当我尝试 运行 使用自定义 JRE 时,它呈现如下错误:
这就是我创建自定义 JRE 的方式(没有错误):
jlink --module-path ..\jmods;%PATH_TO_FX% --add-modules java.base,java.desktop,jdk.unsupported,javafx.graphics --output FXJRE
这就是我尝试 运行(有错误)的方式:
FXJRE\bin\java --module-path %PATH_TO_FX%;mods -m com.javafxdemo/com.javafxdemo.JavaFXDemo
错误信息:
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 javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:280)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:222)
at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:260)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:409)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:94)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
at java.base/java.lang.Thread.run(Thread.java:834)
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: No toolkit found
at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:272)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:409)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
... 5 more
以下是我的编译方式:
来源JavaFXDemo.java:
package com.javafxdemo;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class JavaFXDemo extends Application {
@Override
public void start(Stage stage) {
stage.setTitle("Hello World");
Group root = new Group();
Scene scene = new Scene(root, 300, 250);
Button btn = new Button();
btn.setLayoutX(100);
btn.setLayoutY(80);
btn.setText("Hello World");
btn.setOnAction(actionEvent -> System.out.println("Hello World"));
root.getChildren().add(btn);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
module-info.java
:
module com.javafxdemo {
requires javafx.base;
requires javafx.graphics;
requires javafx.controls;
exports com.javafxdemo;
}
我是这样编译的。
javac -d mods\com.javafxdemo --module-path %PATH_TO_FX% src\com.javafxdemo\module-info.java src\com.javafxdemo\com\javafxdemo\JavaFXDemo.java
编译后,我有如下模块 class 个文件:
├───mods
│ └───com.javafxdemo
│ │ module-info.class
│ │
│ └───com
│ └───javafxdemo
│ JavaFXDemo.class
│
└───src
└───com.javafxdemo
│ module-info.java
│
└───com
└───javafxdemo
JavaFXDemo.java
我可以成功 运行 如下:
java --module-path %PATH_TO_FX%;mods -m com.javafxdemo/com.javafxdemo.JavaFXDemo
不过我可以 运行 使用默认的 JDK11。
如何成功创建自定义 JRE 和 运行 示例 FX 模块程序?
如果您转到此 link,您会注意到每个平台的 JavaFX 发行版有两种风格:
JavaFX SDK 是您正在使用的那个:
export PATH_TO_FX=/path/to/javafx-sdk-11/lib
如果您检查 lib
下的文件,这些是 jar。
另一边的 JavaFX jmods 包含 jmod 格式。
如果您了解 jmod
格式 here:
For most development tasks, including deploying modules on the module path or publishing them to a Maven repository, continue to package modules in modular JAR files. The jmod tool is intended for modules that have native libraries or other configuration files or for modules that you intend to link, with the jlink tool, to a runtime image.
换句话说,如果您使用 javac
或 java
来 运行 您的 jar 或模块,您可以使用 SDK,但如果您使用 jlink
来创建自定义 JRE,您需要 jmod
版本。
一旦你下载了 jmods,解压它们并创建这个变量:
export PATH_TO_FX_JMOD=/path/to/javafx-jmods-11/
现在您可以创建 JRE:
jlink --module-path %PATH_TO_FX_JMOD%;mods --add-modules=com.javafxdemo --output FXJRE
和运行:
FXJRE/bin/java -m com.javafxdemo/com.javafxdemo.JavaFXDemo
Ubuntu18.04,Java11,Netbeans 11.0: 我遇到了与您相同的错误,因为我使用 /usr/share/openjfx/lib 中来自 Ubuntu openjfx 11.0.2+1-1~18.04.2 包的 jars 设置了库 JavaFX11。我想因为这个目录中有相同的 jars 我可以使用它但是你通过从 https://gluonhq.com/products/javafx/ 下载 JavaFX Linux SDK 获得的 javafx-sdk-11.0.2/lib 目录包含很多其他需要的库文件(如 libglass.so)。