使用 Quarkus 或 Springboot 和 JavaFx 的本机可执行文件

问题描述 投票:0回答:2

我正在尝试为与 Quarkus 和 JavaFx 配合使用的应用程序构建本机可执行文件。 我设法实现此目的的唯一方法是将许多 javaFx 类标记为 --initialize-at-run-time,但这会导致在尝试启动应用程序时失败并显示以下消息:

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)   

我想我需要在构建之前添加 javafx 模块,但不知道如何从 Maven 实现这一点。如果有人可以帮助我,我将非常感激。预先感谢。

PS:如果有人知道使用 springboot 的替代解决方案,请分享:)

更新: 使用 SpringBoot 进行测试,但使用 spring-native 和 gluonfx 也失败。

制作了一个最小的可复制版本,您可以从以下位置下载: https://github.com/ikaro143/JavaFx-SpringBoot-example/tree/master

maven 命令应在 VisualStudio Native Tools 命令提示符中执行

要使用 spring 插件构建,请使用:

mvn clean package -Pnative

要使用 gluonfx 进行构建,请使用:

mvn clean gluonfx:build -Pnative-gluonfx

在这两种情况下都会构建 .exe,但两者都不起作用。

从控制台执行 spring 编译会抛出此 stackTrace (执行 gluon 构建不会给出任何反馈,但两者都不起作用):

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

更新: 分享 Quarkus + Jafavx 的最小可重复性

https://github.com/ikaro143/JavaFx-Quarkus-example

要使用 quarkus 插件构建,请使用:

mvn clean package -Pnative

要使用 gluonfx 进行构建,请使用:

mvn clean gluonfx:build -Pnative-gluonfx

Quarkus 方法在分析步骤失败。有以下几个错误:

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)

gluonfx 方式在设置步骤失败,并出现此模糊错误:

[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
javafx quarkus gluon graalvm-native-image spring-native
2个回答
3
投票

已更新José Pereda 的建议后,我尝试将后端迁移到 Micronaut,并能够成功构建本机映像。从 springboot 到 micronaut 的迁移非常容易。只需更改 pom 中的父级和基本依赖项即可。

原生镜像是用maven代码生成的:

mvn clean gluonfx: build -Pnative-gluonfx

也许您需要首先使用目标

gluonfx:runagent
来生成运行所需的配置文件。

根据我的经验,我遇到了一些依赖关系问题,只有在构建完成后运行目标

gluonfx:nativerun
时才会注意到。然后调整代码。

我在这里留下一个最小的例子,以防有人需要: https://github.com/ikaro143/example-micronaut

PS: 确保您的主类已注册用于反射。


0
投票

是否无法创建包含 Spring Boot 和 JavaFx 的本机映像?只有 2 个独立的本机镜像:用于 Spring 和 JavaFX

© www.soinside.com 2019 - 2024. All rights reserved.