java - 使用 JavaFX 11 的自定义 JRE

标签 java javafx jlink 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

我是这样编译的:

JavaFXDe​​mo.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

编译后,我有如下模块类文件:

├───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 发行版有两种风格:

jmods

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.

换句话说,如果您使用javacjava 来运行您的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

关于java - 使用 JavaFX 11 的自定义 JRE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52966195/

相关文章:

java - 如何在orOperator里面使用andOperator

java - 我的 RecyclerView 项目添加代码时出现异常

java - 是否有类似于 swing for eclipse 的 JavaFX 拖放插件?

java - jlink 选项 compress 有什么作用?

java - 将 xml 传递给 jquery 脚本的问题

java - 无法从 Soap 响应中的节点检索文本内容

java - 节点 setMouseTransparent 异常

java - 使用 JMod 插件部署应用程序时出现错误 java.util.zip.ZipException : duplicate entry: classes/META-INF/MANIFEST. MF

java - 使用 java SDK 11.0.6 构建可执行 JavaFX 应用程序

java - Runtime.getruntime().exec() 在 Linux 上不起作用