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

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

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

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

4

1 回答 1

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 开始,如果我成功了,我会用具体的细节更新我的答案。谷歌充斥着无法与 Swing/AWT/JavaFX 一起使用的原生图像的示例,所以我'我不确定我会成功。

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

于 2019-09-28T21:48:28.350 回答