16

I've got an application on Java 8 + JavaFX that I want to migrate to Java 11. The basis aim is to give a .jar to users on a network and so they can use this little application. I'm using JavaFX for the interface and sqlite-jdbc to generate a database.

I've my module-info.java, the compilation seems to be OK: no errors. But if I run the application, I've got this error:

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

My module-info.java

module AutoGeneratorOpenData {
    requires javafx.base;
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.graphics;
    requires sqlite.jdbc;
    requires java.sql;
    requires java.desktop;

    exports autogeneratoropendata;
}

I'm using Netbeans 9 on Windows 10 x64bits and JavaFX Windows SDK (last version 11). I'm not using Maven (but maybe I must?).

Any idea to fix that?

Drimux
  • 336
  • 1
  • 3
  • 10
  • Are you sure this is Java11? As in: https://stackoverflow.com/questions/21185156/javafx-on-linux-is-showing-a-graphics-device-initialization-failed-for-es2-s ... this problem seems to show up rather often. It might as well be a problem with the OS where that JavaFx app is supposed to run on! So dont focus on the JVM version here.Unless the app works on the same machine with Java8, but fails with java11. – GhostCat Oct 25 '18 at 09:25
  • Try running with `-Dprism.verbose=true` to see if that gives more information about the problem. This is indeed not a new problem specific to JavaFX 11, but there are numerous reasons for it happening. – Gimby Oct 25 '18 at 09:27
  • 6
    I had the same problem. There is a JavaFX SDK for download. In this archive there is a bin-folder. In this bin-folder are a lot of dlls and other files, that are needed. In Java 8 they were in the bin-folder automatically. These additional files must be on the path that the application can find them. – Ralf Renz Oct 25 '18 at 09:28
  • Which jar(s) are you using by the way? If I look at the Maven repository, there are operating system specific jars that probably have the necessary native libraries inside of them. I cannot believe you need to manually setup a natives directory, none of the documentation make a reference to needing to do that. – Gimby Oct 25 '18 at 09:47
  • @GhostCat It's indeed Java 11, I'm sure about that (JDK 11 is selected in my Project Properties, in Sources and Libraries). – Drimux Oct 25 '18 at 10:22
  • @Gimby I'm using only sqlite-jdbc-3.23.1.jar when it was on Java 8. I've made only one window with SceneBuilder (with gridpane, tabpane, buttons and some hyperlinks and text, nothing really complex). – Drimux Oct 25 '18 at 10:30
  • @Ralf Renz Indeed, there are some other missing DLL. If I put them directly into my jdk directory bin (not a great deal I know, but I'm testing), it works with a new fxml file with a window with nothing. But other error occurs into my fxml files (which are generated by SceneBuilder - last version): 'Instances of javafx.geometry.Insets cannot be created by FXML loader.' about the padding insets. – Drimux Oct 25 '18 at 10:32
  • @drimux I'm not asking about how you did it using Java 8, I'm asking how you're doing it now with JavaFX 11. You need to include jars to be on the classpath, which ones of JavaFX are you including? Or asked in a different way: how are you compiling and running the application? – Gimby Oct 25 '18 at 10:42
  • @Gimby I begin with JDK 11 and overall the modules. In my modulepath I'm using javafx.controls, javafx.graphics, javafx.fxml, and javafx.base. But I forgot this "opens autogeneratoropendata.controller;" and now it's working! Thank you all. – Drimux Oct 25 '18 at 11:07

5 Answers5

6

So, there are some missing librairies.

  • On Windows, the missing DLL from javafx-sdk-11/bin are at least prism_d3d.dll, prism_sw.dll, javafx_font.dll, glass.dll; you can put all into the jdk directory C:\Program Files\Java\jdk[...]\bin (It's not the best solution), or into the jlink directory for a custom JRE, inside [...]\jlink\bin\ .

  • On Linux, the missing .so from javafx-sdk-11/lib are at least libprism_es2.os, libprism_sw.so, libglass.so, libglassgtk3.so (and libglassgtk2.so probably too for old configuration), libjavafx_font.so, libjavafx_font_freetype.so, libjavafx_font_pango.so; you can put all into the /usr/lib/jvm/java-11[...]/lib for example (It's not the best solution), or into the jlink directory for a custom JRE, inside [...]/jlink/lib .

  • On Mac, the missing .dylib from jav javafx-sdk-11/lib must be (I suppose!) libprism_es2.dylib, libprism_sw.dylib, libglass.dylib, libjavafx_font.dylib [To confirm].

To use the jlink, you should use the jmods - no need to use the librairy files.

And my module-info.java was not really complete:

module AutoGeneratorOpenData {
   requires sqlite.jdbc;
   requires javafx.controls;
   requires javafx.graphics;
   requires java.sql;
   requires java.desktop;
   requires javafx.fxml;
   requires javafx.base;    

   exports autogeneratoropendata;
   exports autogeneratoropendata.controller;    
   exports autogeneratoropendata.model;   
   exports autogeneratoropendata.util;

   opens autogeneratoropendata.controller;
}

Now it's working.

Drimux
  • 336
  • 1
  • 3
  • 10
  • 2
    When you say the native libs are missing, where did you get them from? If you are using `jlink` you don't have to use the JavaFX SDK but the JavaFX `jmods`. See this [answer](https://stackoverflow.com/a/52972960/3956070). – José Pereda Oct 26 '18 at 15:22
  • @JoséPereda When I start my .bat on Windows I've got: 'Graphics Device initialization failed for : d3d, sw' corresponding to prism_d3d.dll, prism_sw.dll (from the JavaFX SDK indeed); then error again about javafx_font and no glass in java.library.path. If I put all DLL, the jlink works. On Linux, on my terminal, I've got the same problem when I start the .sh, I've got: 'Graphics Device initialization failed for : es2, sw', same for the fonts, and 'no glassgtk3 in java.library.path'. If all the .so files are in the lib directory, the script works. But maybe am I wrong about all that? – Drimux Oct 26 '18 at 16:53
  • 1
    Did you check the referred answer? You need the JavaFX jmods if you are using jlink. Those contain the classes and the native libraries for a given platform. – José Pereda Oct 26 '18 at 17:03
  • @JoséPereda indeed it works better with jmods; I'll edit my comment, thank you. By the way, sorry but I don't really understand how and where you create your variable (is it an environment variable?) 'export PATH_TO_FX_JMOD=/path/to/javafx-jmods-11/' - can you be more precise? – Drimux Oct 29 '18 at 09:15
  • The environment variable is for your convenience, you can go with the hardcoded path of course. If you are on a terminal, you can type that, or you can add it to your Windows settings, like you will do with `JAVA_HOME`. – José Pereda Oct 29 '18 at 09:20
4

On Windows, updated PATH variable to contain javafx-sdk-11/bin.

Oly
  • 302
  • 1
  • 8
0

It should also be noted that if you are using Eclipse (Which I know you are not in this case) and Maven, adding dependencies for the platform specific javafx-graphics libraries (win, mac, linux) will cause this issue if you try to build through maven. I'm not entirely sure why.

I was banging my head against a wall trying to just do a clean javafx:run in the goals before I just removed the platform dependent dependencies in the pom and it finally ran.

Chris Toh
  • 88
  • 1
  • 11
0

You may also use:

System.setProperty("java.library.path", "path/to/javafx-sdk-11.0.x/lib");

Where path/to/javafx-sdk-11.0.x/lib is the path to the JavaFX's lib (or for Windows, bin) directory.

Note this technique will work if the JavaFX Application is launched from a secondary class. Launching a JavaFX application directly from it's own class requires the module system (e.g. module-info.java, etc.) since JDK9.

tresf
  • 7,103
  • 6
  • 40
  • 101
  • This is not true. You do not need any module-info.java just to launch a JavaFX9+ program. I even use JavaFX 15 EA and never use a module-info. – mipa Mar 13 '20 at 18:03
  • I'd love to improve the answer with this information. How do you launch a JavaFX application directly without using the new module system in JDK9+? Can you elaborate please? I ask because I can start the application directly using -- for example -- the IntelliJ Run button when using Java 8, but no higher. – tresf Mar 15 '20 at 16:31
  • Just have a look at my public repo here: https://github.com/mipastgt/JFXToolsAndDemos None of the projects has a module-info.java. You can also look at the examples here: https://github.com/openjfx/samples#CLI-Non-Modular-Samples – mipa Mar 15 '20 at 18:19
  • Thanks. I've looked at hellofx, and it too uses a separate class to launch the `Application`. https://github.com/openjfx/samples/blob/master/CommandLine/Non-modular/CLI/hellofx/src/hellofx/Launcher.java. I looked at the `JFXToolsAndDemos`, but it contains several projects. The first I looked at did not extend `Application` so perhaps an exact example could be provided. – tresf Mar 16 '20 at 14:58
  • The Readme is exactly telling you how to run each module. This gives you all the main classes. Just look at the modules and classes ending in ...Demo. – mipa Mar 16 '20 at 18:57
  • Thanks, but the readme uses `mvn:` to execute the programs, which doesn't help non-mvn users. From my understanding, the Java 9+ module system must be used (either through CLI flag or equivalent) to directly launch an FX application. The workaround is to launch by a secondary class. The `Non-Modular-Samples` confirms this. – tresf Mar 17 '20 at 17:22
  • I've edited the solution to clarify that `module-info.java` is one technique (not the only technique) to leverage the new JDK9+ module system. – tresf Mar 17 '20 at 17:22
0

Please use latest JavaFX version, many bugs has been addressed

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-fxml</artifactId>
    <version>15</version>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>15</version>
</dependency>
Prateek Mehta
  • 488
  • 1
  • 8
  • 15