3

I have JavaFx (maven) project and the following run configuration in Intellij:

(mvn) clean javafx:run

This configuration works great on Windows, but on OSx results in the following error:

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:280)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:243)
    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

I googled this error, and it seems to be related to missing JavaFx libs.

However, if I execute the following run configuration:

(mvn) clean package

Then it builds proper JAR that I can then execute on my Mac.

So, I suspect that this might be some problem related to javafx intellij plugin, but I'm not sure about it and how to work around this issue (if this is indeed the issue).

My pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <dependencies>

        <dependency>
            <groupId>com.google.code.findbugs</groupId>
            <artifactId>jsr305</artifactId>
            <version>3.0.2</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>4.6</version>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>12.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>12.0.2</version>
        </dependency>

        <!-- the reason for having these dependency for all classifiers is here: https://stackoverflow.com/a/52654791/2463035-->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics </artifactId>
            <version>12.0.2</version>
            <classifier>win</classifier>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics </artifactId>
            <version>12.0.2</version>
            <classifier>linux</classifier>
        </dependency>

        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics </artifactId>
            <version>12.0.2</version>
            <classifier>mac</classifier>
        </dependency>

    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.fxml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>

        <plugins>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.3</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>com.app.MyApplication</mainClass>
                        </configuration>
                    </execution>
                    <execution>
                        <!-- Configuration for debugging -->
                        <id>debug</id>
                        <configuration>
                            <options>
                                <option>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005</option>
                            </options>
                            <mainClass>com.app.MyApplication</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals><goal>shade</goal></goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">

                                    <mainClass>com.app.MainClass</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

</project>

The last entry in the log after execution of mvn clean -X javafx:run:

Executing command line: [C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\jbr\bin\java.exe, --module-path, C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-base\12.0.2\javafx-base-12.0.2-win.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-base\12.0.2\javafx-base-12.0.2.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-controls\12.0.2\javafx-controls-12.0.2-win.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-controls\12.0.2\javafx-controls-12.0.2.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-fxml\12.0.2\javafx-fxml-12.0.2-win.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-fxml\12.0.2\javafx-fxml-12.0.2.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-graphics\12.0.2\javafx-graphics-12.0.2-linux.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-graphics\12.0.2\javafx-graphics-12.0.2-mac.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-graphics\12.0.2\javafx-graphics-12.0.2-win.jar
C:\Users\Vasiliy\.m2\repository\org\openjfx\javafx-graphics\12.0.2\javafx-graphics-12.0.2.jar, --add-modules, javafx.base,javafx.controls,javafx.fxml,javafx.graphics,javafx.graphics,javafx.graphics, -classpath, C:\Users\Vasiliy\projects\wellsense-annotator\target\classes
C:\Users\Vasiliy\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar
C:\Users\Vasiliy\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar
C:\Users\Vasiliy\.m2\repository\com\google\code\findbugs\jsr305\3.0.2\jsr305-3.0.2.jar
C:\Users\Vasiliy\.m2\repository\com\google\code\gson\gson\2.8.5\gson-2.8.5.jar
C:\Users\Vasiliy\.m2\repository\com\opencsv\opencsv\4.6\opencsv-4.6.jar
C:\Users\Vasiliy\.m2\repository\commons-beanutils\commons-beanutils\1.9.3\commons-beanutils-1.9.3.jar
C:\Users\Vasiliy\.m2\repository\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar
C:\Users\Vasiliy\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar
C:\Users\Vasiliy\.m2\repository\org\apache\commons\commons-collections4\4.2\commons-collections4-4.2.jar
C:\Users\Vasiliy\.m2\repository\org\apache\commons\commons-lang3\3.8.1\commons-lang3-3.8.1.jar
C:\Users\Vasiliy\.m2\repository\org\apache\commons\commons-text\1.3\commons-text-1.3.jar
C:\Users\Vasiliy\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar, com.wellsensevu.MyApplication]

Any help will be greatly appreciated.

Vasiliy
  • 16,221
  • 11
  • 71
  • 127
  • JavaFX modules have different native libraries (even some different classes) for each platform, so a given jar won't run on a different platform. However, your pom should be platform-agnostic, and `mvn clean javafx:run` should work fine on all the platforms. Can you post your pom? – José Pereda Sep 22 '19 at 11:53
  • @JoséPereda, I added pom.xml to the question. Note: JAR obtained with `package` does run on all platforms. It's only the run configuration that I use during development on Mac's Intellij that doesn't work. – Vasiliy Sep 22 '19 at 12:23

1 Answers1

1

When you add the three classifiers for javafx-graphics, this solves the issue of building a fat cross-platform jar.

However, running your pom on Mac, from the terminal (it is not an IntelliJ issue), it fails, with the posted error (No toolkit found).

If you run: mvn clean -X javafx:run, you will find the reason for that exception:

[DEBUG] Executing command line: [.../Contents/Home/bin/java, \
--module-path, .../target/classes:\
.../.m2/repository/org/openjfx/javafx-base/13/javafx-base-13-mac.jar:\
.../.m2/repository/org/openjfx/javafx-controls/13/javafx-controls-13-mac.jar:\
.../.m2/repository/org/openjfx/javafx-fxml/13/javafx-fxml-13-mac.jar:\
.../.m2/repository/org/openjfx/javafx-graphics/13/javafx-graphics-13-linux.jar:\
.../.m2/repository/org/openjfx/javafx-graphics/13/javafx-graphics-13-mac.jar:\
.../.m2/repository/org/openjfx/javafx-graphics/13/javafx-graphics-13-win.jar,\
--add-modules,...]

Notice that it shows the linux classifier in the first place, because the artifacts are sorted alphanumerically, and the three jars actually refer to the same module javafx-graphics.

Since --module-path will only resolve the first occurrence of a given module (see JEP 261 or this answer), ignoring the others, mvn clean javafx:run will only work on Linux.

In conclusion, with your current pom, the fat cross-platform jar will work on Linux, Mac and Windows, and javafx:run will only run on Linux.

Solution

To prevent the need of commenting out the graphic dependency with classifiers every time you want to run javafx:run, while keeping them for building the shade plugin, the solution, based on this answer, is the following:

  • Remove the three javafx-graphic dependencies from your pom
  • Add the following profile to your pom, including those three dependencies:
<profiles>
        <profile>
            <id>shadeProfile</id>
            <dependencies>
                <dependency>
                    <groupId>org.openjfx</groupId>
                    <artifactId>javafx-graphics</artifactId>
                    <version>13</version>
                    <classifier>win</classifier>
                </dependency>
                <dependency>
                    <groupId>org.openjfx</groupId>
                    <artifactId>javafx-graphics</artifactId>
                    <version>13</version>
                    <classifier>mac</classifier>
                </dependency>
                <dependency>
                    <groupId>org.openjfx</groupId>
                    <artifactId>javafx-graphics</artifactId>
                    <version>13</version>
                    <classifier>linux</classifier>
                </dependency>
            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-shade-plugin</artifactId>
                        <version>3.2.1</version>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>shade</goal>
                                </goals>
                                <configuration>
                                    <transformers>
                                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                            <mainClass>com.app.MainClass</mainClass>
                                        </transformer>
                                    </transformers>
                                    <shadedClassifierName>shaded</shadedClassifierName>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

To run this profile, you will need to run:

mvn -PshadeProfile package

This will include all the existing dependencies in your pom, and will additionally include the extra three jars.

Now both mvn clean javafx:run and java -jar yourShade.jar should work on Linux, Mac and Windows.

José Pereda
  • 44,311
  • 7
  • 104
  • 132
  • Thanks a lot, it worked! Just FYI, the original configuration worked on Windows (don't know about Linux). – Vasiliy Sep 22 '19 at 15:23
  • Good to know. Windows failed for me with the sample I used, running from a terminal. If you add `-X` do you also have graphics:linux first? – José Pereda Sep 22 '19 at 15:26
  • I attached the output of `mvn clean -X javafx:run` (before the fix) on win at the end of the question. Thanks again for your help. – Vasiliy Sep 23 '19 at 10:42