为什么我的 JavaFX 应用程序的运行时映像(由 jlink 组装)无法启动并正常工作?

ktm*_*124 6 java javafx jlink java-module

我有一个简单的 JavaFX Web 浏览器,它是一个模块。该模块的目录结构为:

webBrowser
webBrowser/module-info.java
webBrowser/webbrowser
webBrowser/webbrowser/WebBrowser.java
Run Code Online (Sandbox Code Playgroud)

这是 module-info.java 的代码

module webBrowser {
    requires javafx.controls;
    requires javafx.web;
    exports webbrowser;
}
Run Code Online (Sandbox Code Playgroud)

以下是 WebBrowser.java 的代码:

package webbrowser;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;

public class WebBrowser extends Application {

    @Override
    public void start(Stage stage) {
        WebView browser = new WebView();
        WebEngine webEngine = browser.getEngine();
        webEngine.load("http://www.oracle.com");
        Scene scene = new Scene(browser, 1200, 900);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}
Run Code Online (Sandbox Code Playgroud)

我用 javac 编译我的模块化应用程序:

% javac -d out --module-source-path . --module-path $JAVAFX --module webBrowser
Run Code Online (Sandbox Code Playgroud)

我可以使用 java 启动我的应用程序并且运行良好:

% java --module-path out:$JAVAFX/lib --module webBrowser/webbrowser.WebBrowser
Run Code Online (Sandbox Code Playgroud)

当我尝试使用 jlink 组装我的模块(webBrowser)和 JavaFX 模块时,问题就开始了:

% jlink --module-path out:$JAVAFX/lib --add-modules webBrowser,javafx.controls,javafx.web --output myjre
% myjre/bin/java --list-modules
java.base@17.0.1
java.datatransfer@17.0.1
java.desktop@17.0.1
java.net.http@17.0.1
java.prefs@17.0.1
java.xml@17.0.1
javafx.base
javafx.controls
javafx.graphics
javafx.media
javafx.web
jdk.jsobject@17.0.1
jdk.unsupported@17.0.1
jdk.xml.dom@17.0.1
webBrowser
% myjre/bin/java --module webBrowser/webbrowser.WebBrowser
Graphics Device initialization failed for :  es2, 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:283)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:254)
    at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:264)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:291)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:163)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:659)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:410)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
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:95)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
    at java.base/java.lang.Thread.run(Thread.java:833)
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:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.RuntimeException: No toolkit found
    at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:276)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:291)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:163)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:659)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:410)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
    ... 5 more
Run Code Online (Sandbox Code Playgroud)

当运行我的链接应用程序(上面)时,我得到这个 RuntimeException:

java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
Run Code Online (Sandbox Code Playgroud)

组装注意事项

我使用 jlink 来组装三个模块:javafx.controls、javafx.web 和 webBrowser。

问题

我的应用程序使用 Java 运行良好。当我使用以下命令时,它会启动并正常工作:

% java --module-path out:$JAVAFX/lib --module webBrowser/webbrowser.WebBrowser
Run Code Online (Sandbox Code Playgroud)

但当我尝试启动运行时图像时,我收到一条错误消息(初始化 QuantumRenderer 时出错:未找到合适的管道):

% myjre/bin/java --module webBrowser/webbrowser.WebBrowser
Run Code Online (Sandbox Code Playgroud)

当我尝试启动运行时映像时,为什么会收到此错误消息?如何正确组装和启动我的网络浏览器?

jew*_*sea 6

请参阅openjfx 跟踪器中的相关问题,并尝试按照其中的建议和故障排除步骤进行操作。

特别是本节有关下载和使用 mod 文件而不是 sdk 的内容。

原因是您正在捆绑 SDK 中的“mod”,其中没有本机库(在 SDK 中,我们有 jar 和本机库)。

您可以将 JavaFX 模块下载为 jmod,包括类和本机库。

看:

并下载 mods(而不是 SDK)。

接下来,将jlink指向mods目录

显然,SDK 打包与 Maven 等其他发行版类型不同。SDK 打包将 Java 类和本机库分开,而其他交付平台的打包则不然,这就是为什么您可以针对 SDK 执行,但不能链接它。

请参阅openjfx 文档中有关从命令行创建运行时的部分。jlink 命令中使用的路径如下

--module-path $PATH_TO_FX_MODS:mods
Run Code Online (Sandbox Code Playgroud)

不是

--module-path out:$JAVAFX/lib
Run Code Online (Sandbox Code Playgroud)