Swing 应用程序的 Graal 原生图像:在图像堆中检测到一个已启动的线程

Alf*_*Alf 5 java swing graalvm

public class SimpleApp {
    public static void main( String[] args ) {
        JOptionPane.showMessageDialog(null, "Ciao", "Info", JOptionPane.INFORMATION_MESSAGE);
    }
} 
Run Code Online (Sandbox Code Playgroud)

当我尝试使用创建本机图像时,native-image --no-fallback我得到了这个:

错误:在图像堆中检测到一个已启动的线程。在图像生成器中运行的线程不再在图像运行时运行。该对象可能是由类初始值设定项创建的,并且可以从静态字段访问。默认情况下,所有类初始化都在本机映像构建期间完成。您可以使用选项 -H:ClassInitialization= 手动将类初始化延迟到映像运行时。或者您可以编写自己的初始化方法并从主入口点显式调用它们。

详细信息: Trace: object sun.java2d.opengl.OGLRenderQueue field sun.java2d.opengl.OGLRenderQueue.theInstance

Ner*_*Dad 3

这都与何时应该初始化类有关——GraalVM 团队有一篇关于此主题的更新文章: https://medium.com/graalvm/updates-on-class-initialization-in-graalvm-native-图像生成-c61faca461f7

简短版本:使用跟踪(在比您的 Graal 包更新版本中添加的)来查找有问题的类,然后将它们设置为在运行时初始化。说起来容易,做起来难。无论如何,我刚刚在 19.2(企业)版本和一些包含 AWT 的随机代码中遇到了同样的问题。不过,该消息已更改(为了清晰起见,略有编辑):

错误:在图像堆中检测到已启动的线程。在图像生成器中运行的线程不再在图像运行时运行。要查看该对象是如何实例化的,请使用-H:+TraceClassInitialization. 该对象可能是由类初始值设定项创建的,并且可以从静态字段访问。您可以使用选项在图像运行时请求类初始化 --initialize-at-build-time=<class-name>。或者您可以编写自己的初始化方法并从主入口点显式调用它们。 Trace: object sun.awt.AWTAutoShutdown method sun.awt.AWTAutoShutdown.getInstance()

我将解决这个问题(可能从相当于“Hello World”的 AWT 开始,如果成功,我将用具体细节更新我的答案。Google 上到处都是不与 Swing/AWT/JavaFX 一起使用的本机图像的示例,所以我不确定我会成功。

免责声明:我在 Oracle 工作,但不是在与 Graal 开发人员密切相关的组织中(可能没有共同的经理)。我所说的一切都是我的意见。