3

I'm Using JDK11 and JavaFX11.

I created a custom JRE for my sample FX module program using Jlink, but when I try to run with the custom JRE, it renders errors as below:

This is how I created my custom JRE (no errors):

jlink --module-path ..\jmods;%PATH_TO_FX% --add-modules java.base,java.desktop,jdk.unsupported,javafx.graphics --output FXJRE

This is how I tried to run (with errors):

FXJRE\bin\java --module-path %PATH_TO_FX%;mods -m com.javafxdemo/com.javafxdemo.JavaFXDemo

The error messages:

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

Here is how I compiled:

The source JavaFXDemo.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;
}

This is how I compiled.

javac -d mods\com.javafxdemo --module-path %PATH_TO_FX% src\com.javafxdemo\module-info.java src\com.javafxdemo\com\javafxdemo\JavaFXDemo.java

After compilation, I have module class files as below:

├───mods
│   └───com.javafxdemo
│       │   module-info.class
│       │
│       └───com
│           └───javafxdemo
│                   JavaFXDemo.class
│
└───src
    └───com.javafxdemo
        │   module-info.java
        │
        └───com
            └───javafxdemo
                    JavaFXDemo.java

I can successfully run as below:

java --module-path %PATH_TO_FX%;mods -m com.javafxdemo/com.javafxdemo.JavaFXDemo

I can run with the default JDK11 though.

How can I successfully create a custom JRE and run the sample FX module program with it?

Lii
  • 11,553
  • 8
  • 64
  • 88
KBee
  • 87
  • 1
  • 5

2 Answers2

4

If you go to this link, you will notice there are two flavors for the JavaFX distribution for each platform:

jmods

The JavaFX SDK is the one you are using as:

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

and if you check the files under lib, these are jars.

The JavaFX jmods on the other side contains the jmod format.

And if you read about the jmod format 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.

In other words, if you use javac or java to run your jar or module you can use the SDK, but if you are using jlink to create a custom JRE, you need the jmod version.

Once you have downloaded the jmods, unzip them and create this variable:

export PATH_TO_FX_JMOD=/path/to/javafx-jmods-11/

Now you can create the JRE:

jlink --module-path %PATH_TO_FX_JMOD%;mods --add-modules=com.javafxdemo --output FXJRE

and run:

FXJRE/bin/java -m com.javafxdemo/com.javafxdemo.JavaFXDemo
José Pereda
  • 44,311
  • 7
  • 104
  • 132
  • It perfectly answered my question, José Pereda. By the way, do we not need to add **java.base** module when creating a custom JRE? It was my habit but now, it seems not required. Are modules automatically added if they are required in the **module-info.java**? – KBee Oct 25 '18 at 01:25
  • For jlink you need your module only, you added all the requirements to the module info file. – José Pereda Oct 25 '18 at 01:57
  • Also for module-info you don’t need to add base nor graphics if you are adding controls, as it already depends on them. – José Pereda Oct 25 '18 at 02:01
1

Ubuntu 18.04, Java 11, Netbeans 11.0: I had the same error as you because I set up Library JavaFX11 using the jars in /usr/share/openjfx/lib which are from the Ubuntu openjfx 11.0.2+1-1~18.04.2 package. I thought because the same jars were in this directory I could use it but the javafx-sdk-11.0.2/lib directory you get by downloading JavaFX Linux SDK from https://gluonhq.com/products/javafx/ contains many other library files (like libglass.so) which ARE needed.

Chris Good
  • 156
  • 10