Vasiliy
Vasiliy

Reputation: 16268

Can't run JavaFx application from Intellij on OSx (Mac)

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.

Upvotes: 4

Views: 1265

Answers (1)

Jos&#233; Pereda
Jos&#233; Pereda

Reputation: 45486

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.

Upvotes: 1

Related Questions