使用javaFX 11自定义jre

我正在使用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发行版有两种:

使用javaFX 11自定义jre

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
上一篇:使用Renesas e2studio软件JLINK下载到板子上,解决JLINK连接不上问题


下一篇:从Mathematica到Java的图像