【问题标题】:Custom JRE with JavaFX 11使用 JavaFX 11 的自定义 JRE
【发布时间】:2019-03-28 16:53:22
【问题描述】:

我正在使用 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 模块程序?

【问题讨论】:

    标签: java javafx jlink javafx-11


    【解决方案1】:

    如果您访问此link,您会注意到每个平台的 JavaFX 发行版有两种风格:

    JavaFX SDK 是您使用的那个:

    export PATH_TO_FX=/path/to/javafx-sdk-11/lib
    

    如果你检查lib 下的文件,这些都是罐子。

    另一边的 JavaFX jmods 包含 jmod 格式。

    如果您了解jmod 格式here

    对于大多数开发任务,包括在模块路径上部署模块或将它们发布到 Maven 存储库,请继续将模块打包到模块化 JAR 文件中。 jmod 工具适用于具有本机库或其他配置文件的模块,或者适用于您打算使用 jlink 工具链接到运行时映像的模块。

    换句话说,如果您使用javacjava 运行您的jar 或模块,您可以使用SDK,但如果您使用jlink 创建自定义JRE,您需要jmod 版本.

    下载 jmod 后,解压缩并创建此变量:

    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
    

    【讨论】:

    • 它完美地回答了我的问题,何塞·佩雷达。顺便说一句,我们在创建自定义 JRE 时不需要添加 java.base 模块吗?这是我的习惯,但现在,似乎不需要。如果 module-info.java 中需要模块,是否会自动添加它们?
    • 对于 jlink,您只需要您的模块,您已将所有要求添加到模块信息文件中。
    • 另外,对于模块信息,如果要添加控件,则无需添加基础或图形,因为它已经依赖于它们。
    【解决方案2】:

    Ubuntu 18.04、Java 11、Netbeans 11.0: 我遇到了与您相同的错误,因为我使用来自 Ubuntu openjfx 11.0.2+1-1~18.04.2 软件包的 /usr/share/openjfx/lib 中的 jar 设置了 Library JavaFX11。我想因为这个目录中有相同的 jar,我可以使用它,但是通过从 https://gluonhq.com/products/javafx/ 下载 JavaFX Linux SDK 获得的 javafx-sdk-11.0.2/lib 目录包含许多其他库文件(如 libglass.so),它们是需要。

    【讨论】:

      猜你喜欢
      • 2021-12-04
      • 2017-01-21
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 1970-01-01
      • 2019-07-02
      相关资源
      最近更新 更多