I am trying to build a native executable for an app that works with Quarkus and JavaFx. The only way I have managed to achieve this has been marking lots of javaFx classes as --initialize-at-run-time, but this causes that, when trying to start the app, it fails with the following message:
java.lang.ClassNotFoundException: com.sun.javafx.tk.quantum.QuantumToolkit
at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:71)
at java.lang.Class.forName(DynamicHub.java:1319)
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:251)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.lang.Thread.run(Thread.java:829)
at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:567)
at com.oracle.svm.core.windows.WindowsJavaThreads.osThreadStartRoutine(WindowsJavaThreads.java:138)
2021-09-09 16:02:21,173 ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): java.lang.RuntimeException: No toolkit found
at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:273)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:158)
at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.lang.Thread.run(Thread.java:829)
at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:567)
at
com.oracle.svm.core.windows.WindowsJavaThreads.osThreadStartRoutine(WindowsJavaThreads.java:138)
I guess I need to add the javafx modules before build, but don't know how to achieve this from Maven. If anyone can help me I would be very grateful. Thanks in advance.
PS: If someone knows an alternative solution using springboot please share :)
Updated: Tested with SpringBoot and also fails with spring-native and gluonfx.
Made a minimal reproducible you can download from: https://github.com/ikaro143/JavaFx-SpringBoot-example/tree/master
The maven commands should be executed in the VisualStudio Native Tools Command Promp
To build with spring plugin use: mvn clean package -Pnative
To build with gluonfx use: mvn clean gluonfx:build -Pnative-gluonfx
In both cases the .exe is built, but none of both works.
Executing spring compilation from the console throws this stackTrace (Execution of gluon build does not give any feedback but neither works):
Exception in thread "main" java.lang.RuntimeException: Application launch error
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:202)
at java.lang.Thread.run(Thread.java:829)
at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:567)
at com.oracle.svm.core.windows.WindowsJavaThreads.osThreadStartRoutine(WindowsJavaThreads.java:138)
Caused by: java.lang.AssertionError: java.lang.ClassNotFoundException: javafx.scene.image.Image
at com.sun.javafx.util.Utils.forceInit(Utils.java:868)
at com.sun.javafx.tk.Toolkit.<clinit>(Toolkit.java:945)
at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:286)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:160)
at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:658)
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:678)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
... 3 more
Caused by: java.lang.ClassNotFoundException: javafx.scene.image.Image
at com.oracle.svm.core.hub.ClassForNameSupport.forName(ClassForNameSupport.java:71)
at java.lang.Class.forName(DynamicHub.java:1319)
at com.sun.javafx.util.Utils.forceInit(Utils.java:865)
... 11 more
Updated: Sharing a minimal reproducible for Quarkus + Jafavx
https://github.com/ikaro143/JavaFx-Quarkus-example
To build with quarkus plugin use: mvn clean package -Pnative
To build with gluonfx use: mvn clean gluonfx:build -Pnative-gluonfx
The Quarkus way fails at analysis step. With several errors as below:
analysis: 45,621.43 ms, 3.89 GB
Error: Unsupported features in 12 methods
Detailed message:
Error: Class initialization of com.sun.javafx.tk.quantum.PrismImageLoader2$AsyncImageLoader failed. Use the option --initialize-at-run-time=com.sun.javafx.tk.quantum.PrismImageLoader2$AsyncImageLoader to explicitly request delayed initialization of this class.
Original exception that caused the problem: java.lang.ExceptionInInitializerError
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1042)
at jdk.unsupported/sun.misc.Unsafe.ensureClassInitialized(Unsafe.java:698)
at jdk.internal.vm.compiler/org.graalvm.compiler.serviceprovider.GraalUnsafeAccess.ensureClassInitialized(GraalUnsafeAccess.java:77)
The gluonfx way fails at setup step with this vague error:
[com.quarkusjavafx.example.applauncher.cdiapplication:9740] classlist: 3,592.40 ms, 1.19 GB
[com.quarkusjavafx.example.applauncher.cdiapplication:9740] (cap): 3,086.44 ms, 1.19 GB
[com.quarkusjavafx.example.applauncher.cdiapplication:9740] setup: 6,095.10 ms, 1.19 GB
Fatal error:java.lang.NullPointerException
at java.base/java.io.Reader.<init>(Reader.java:167)
at java.base/java.io.InputStreamReader.<init>(InputStreamReader.java:72)
at io.quarkus.runtime.graal.ResourcesFeature.beforeAnalysis(ResourcesFeature.java:21)
at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$11(NativeImageGenerator.java:691)
at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:71)
at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:691)
at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:532)
at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:491)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:380)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:543)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:119)
at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:573)
[com.quarkusjavafx.example.applauncher.cdiapplication:9740] [total]: 9,723.35 ms, 1.19 GB