简体   繁体   中英

Why doesn't the runtime image (assembled by jlink) for my JavaFX application launch and work correctly?

I have a simple JavaFX web browser that is a module. The directory structure of the module is:

webBrowser
webBrowser/module-info.java
webBrowser/webbrowser
webBrowser/webbrowser/WebBrowser.java

Here is the code to module-info.java

module webBrowser {
    requires javafx.controls;
    requires javafx.web;
    exports webbrowser;
}

Here is the code to 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();
    }
}

I compile my modular application with javac:

% javac -d out --module-source-path . --module-path $JAVAFX --module webBrowser

I'm able to launch my application with java and it works fine:

% java --module-path out:$JAVAFX/lib --module webBrowser/webbrowser.WebBrowser

The trouble starts when I try to assemble my module (webBrowser) and the JavaFX modules using jlink:

% 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

When running my linked application (above), I get this RuntimeException:

java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found

Notes on assembly

I'm using jlink to assemble three modules: javafx.controls, javafx.web, and webBrowser.

Question

My application runs fine with Java. It launches and works correctly when I use this command:

% java --module-path out:$JAVAFX/lib --module webBrowser/webbrowser.WebBrowser

But I get an error message (Error initializing QuantumRenderer: no suitable pipeline found) when I try to launch the runtime image:

% myjre/bin/java --module webBrowser/webbrowser.WebBrowser

Why do I get this error message when I try to launch the runtime image? How can I get my web browser to assemble and launch correctly?

See this related issue in the openjfx tracker and try following the advice and troubleshooting steps there.

Especially this section on downloading and using the mod files instead of the sdk.

The reason is that you are bundling the "mods" from the SDK, which don't have the native libraries in them (in the SDK, we have jars and native libs).

You can download the JavaFX modules as jmods, including classes and native libs.

See:

and download the mods (instead of the SDK).

Next, point jlink to the mods directory

Apparently the SDK packaging is different than other distribution types like Maven. The SDK packaging separates the Java classes and native libraries, whereas packaging for other delivery platforms do not, which is why you can execute against the SDK, but not link against it.

See the openjfx docs section on creating a runtime from the command line. The path to use in the jlink command is given as

--module-path $PATH_TO_FX_MODS:mods

not

--module-path out:$JAVAFX/lib

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM