0

I have a Problem with Deploying my JavaFX Project to a .jar or .exe File to easily execute it (and achive the Project Requirements). I am trying to get it to work as a .jar File because I think thats the easier Way to go but maybe I am wrong so it would be awesome if you could help me solve this Problem.

I already tried using the Artifacts from Intellij but this is not working. I get an Errormessage which says "Error: JavaFX runtime components are missing, and are required to run this application". Then I tried using another Way which I found on the Internet: https://github.com/openjfx/samples/tree/master/CommandLine/Non-modular/CLI but this is resulting in exactly the same message when trying to package it to a .jar File.

All of the above I tried on my existing Project and on a completely new one with nothing inside except the prewirtten Stuff from Intellij when you create a new JavaFX Project.

My Project exists of nothing like Maven or Gradle, I just have a basic JavaFX Project (JavaFX 15 and Java 15) with one additional Library: org.json:json version 20201115

I hope these Informations are enough for you to understand my Problem and hopefully help me, but if not just ask for what you need and I will do my best to provide it to you.

Thanks for helping :)

Best Regards

Maxi

Edit: Errormessage associated to comment below

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:244)
        at javafx.graphics/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:261)
        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:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        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:94)
        at javafx.graphics/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:124)
        at java.base/java.lang.Thread.run(Thread.java:832)
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:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        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:273)
        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
Maxi
  • 207
  • 3
  • 15
  • Why using an outdated JavaFX 11 when you are already using Java 15 anyway? – mipa Jan 23 '21 at 13:55
  • i thought because javafx 11 is for long term support but do you suggest to upgrade to javafx 15? and will this be easily done and help me to reach my goal of getting a jar which i can run? – Maxi Jan 23 '21 at 16:01
  • the first step is to use jlink to create a custom jre. then a platform-dependent (native) launcher is made to launch jvm with the appropriate parameters for your application. at the end, an installation package (native) is made to copy everything on the client machine. – mr mcwolf Jan 23 '21 at 17:40
  • @mrmcwolf i tried to create a new project to test step by step as explained at https://openjfx.io/openjfx-docs/#IDE-Intellij (under modular from IDE) but if i run the last command from step 7 i get an error -> i added the errormessage to my question – Maxi Jan 23 '21 at 18:00
  • @Maxi use latest javafx. – mr mcwolf Jan 23 '21 at 18:20
  • JavaFX 11 is long-term support _if you pay for it_, unless I'm mistaken. – Slaw Jan 23 '21 at 21:17
  • LTS for an outdated version of JavaFX does not make much sense if you are using the latest Java version anyway. Especially when you bundle your app with a JRE always use the latest version of Java and JavaFX. Upgrading from JavaFX 11 to 15 should be completely painless (if not even unnoticeable). – mipa Jan 24 '21 at 11:16
  • I upgraded now to javafx 15 (thanks for that hint) but it did not help me to get closer to my goal of getting a jar file which i can execute. I get the same error as mentioned in my comment to mrmcwolf – Maxi Jan 24 '21 at 15:43

1 Answers1

0

this might not concern your particular situation, but maybe it can give you a hint.

Short explanation

I solved the "Error initializing QuantumRenderer: no suitable pipeline found" by manually including library-files to the fat JAR and adding them to the classpath, which is used for execution, with the assistance of Gradle. I included:
  • the required openJFX-JARs from my system's openJFX installation
  • the accompanying C++ libraries like the renderer libprism_sw.so (*.so on linux, *.dll on Windows)

The hint for the libs came from JavaFX on Linux is showing a "Graphics Device initialization failed for : es2, sw"

  • "The problem can be in your old JRE version, which doesn't contain all the necessary libraries, such as libprism_es2.so or libglass.so, which should be located in /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64."
  • ...
  • "Download latest JRE from the official Oracle website and copy lib folder to your current JRE location. That should be enough."

Full explanation

"Error initializing QuantumRenderer" Problem

I had a similar problem with a fat JAR filled with several JFX-example classes from the code for a Java-book. The project uses Gradle for build management and runs the JFX-examples using the fat JAR (build/libs/Java-Profi-all.jar).

The "Error initializing QuantumRenderer" appeared when I tried to execute a simple HelloWorld example for JFX (FirstJavaFxExample) on the command line using bin/java of my current JRE without using Gradle. I almost solved the issue with the hints on JavaFX on Linux is showing a "Graphics Device initialization failed for : es2, sw" , but I got stuck on the same error in the end. Even if I added the required openJFX-JARs and accompanying C++ libraries in the fat JAR and to the classpath via "-cp ...:projectdir/build/requiredLibs".

Used command:

/usr/lib64/jvm/java-1.8.0-openjdk-1.8.0/bin/java -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -Dprism.verbose=true -cp projectdir/build/libs/Java-Profi-all.jar:projectdir/build/requiredLibs ch14_javafx.basics.FirstJavaFxExample

Error:

Prism pipeline init order: es2 sw 
Using java-based Pisces rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
Prism pipeline name = com.sun.prism.es2.ES2Pipeline
Loading ES2 native library ... prism_es2
GraphicsPipeline.createPipeline failed for com.sun.prism.es2.ES2Pipeline
java.lang.UnsatisfiedLinkError: Can't load library: projectdir/build/libs/amd64/libprism_es2.so
*** Fallback to Prism SW pipeline
Prism pipeline name = com.sun.prism.sw.SWPipeline
GraphicsPipeline.createPipeline failed for com.sun.prism.sw.SWPipeline
java.lang.UnsatisfiedLinkError: Can't load library: projectdir/build/libs/amd64/libprism_sw.so
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
Caused by: java.lang.RuntimeException: No toolkit found

Found solutions with Gradle

I found two solutions, only the first using a fat JAR:
  1. quick-n-dirty solution with pseudo-launcher class using fat JAR
  2. long term solution with Jmods/modularization (not working with fat JAR for me)

I couln't make the long term solution work with the fat JAR Java-Profi-all.jar. Anyway you can find further infos about the modular solution here:

quick-n-dirty solution with fat JAR

In order to execute the class ch14_javafx.basics.FirstJavaFxExample with Gradle I wrote the class JfxEdencodingDirtyFixLauncher in the same package:

package ch14_javafx.basics;

public class JfxEdencodingDirtyFixLauncher {
    public static void main(String[] args){
        FirstJavaFxExample.main(args);
    }
}

Additionally I made the following modifications on build.gradle:

A) Ensuring the fitting JRE-version for the used openjfx-version.

sourceCompatibility=1.11
targetCompatibility=1.11

B) manually including the openjfx-JARs and C++ libraries (*.so) to the build-configuration (due to my linux installation):

dependencies
{
...
    compile fileTree('/usr/local/manuell/javafx-sdk-11.0.2/lib/') { include '*.jar' }
    runtime fileTree('/usr/local/manuell/javafx-sdk-11.0.2/lib/') { include '*' } // also inlcude *.so files for JNI-access
...

The gradle.build-script later copies these *.jar and *.so files to a the subfolder requiredLibs and adds them to the classpath when building the JAR jar:

...
task copyRequiredLibs(type: Copy) {
   from configurations.runtime
   into "$buildDir/libs/requiredLibs"
}


jar {
  dependsOn copyRequiredLibs
  
  baseName = "Java-Profi-all"
  
  manifest {
    attributes(
               "Created-By"             : "Michael Inden",
                    "Specification-Title"    : "Java-Profi",
                    "Specification-Version"  : "3",
                    "Specification-Vendor"   : "Michael Inden",
                    "Implementation-Title"   : "Java-Profi",
                    "Implementation-Version" : "3",
                    "Implementation-Vendor"  : "Michael Inden",      
      "Class-Path": configurations.runtime.collect { "requiredLibs/" + it.getName() }.join(' '))
  }
  
  // JAR-Dateien mit aufnehmen, dann kann man diese bei Bedarf separat entpacken
  into('requiredLibs') {
    FileCollection collection = files("$buildDir/libs/requiredLibs")
    from { collection.collect { it } }
  }  
...

For execution of the fat JAR with custom gradle tasks, I added a task definition to the predefined appTasks.txt file:

task JfxEdencodingDirtyFixLauncher              (dependsOn: jar, group: 'Java_Profi_Chapter_14') {doLast { executeClass("ch14_javafx.basics.JfxEdencodingDirtyFixLauncher")  }} 

This task can then be executed using the fat JAR with this command:

gradle JfxEdencodingDirtyFixLauncher

See also:

Blem
  • 16
  • 2