◀返回
排查 Native Image 运行时错误
即使预先编译成功,生成的映像仍可能在运行时崩溃,或者其行为与应用程序在 Java VM 上的行为不同。本指南将介绍一些导致此类问题的原因,并提供诊断和解决这些问题的策略。
请注意,有时升级到最新版本的 GraalVM 即可解决问题。
1. 诊断缺失的元数据注册
首先诊断是否存在任何缺失的元数据配置。Native Image 要求在构建期间已知所有已使用的类。静态分析会尝试预测应用程序的运行时行为。在某些情况下,您需要为分析提供配置,以便使其可见所有动态特性调用。如果未能这样做,一旦在应用程序中使用动态特性,生成的映像将在运行时终止,并出现难以诊断的错误。通过主动检查缺失的元数据可以避免这种情况。
-
将
--exact-reachability-metadata
选项传递给native-image
工具并重建应用程序。如果您只想针对特定包执行此操作,请指定包前缀--exact-reachability-metadata=[package prefix]
。此选项在 GraalVM for JDK 23 中引入,用于调试。在 JDK 23 之前的 GraalVM 版本中,请改用
-H:ThrowMissingRegistrationErrors=
构建选项。 -
运行生成的本机可执行文件,并传递
-XX:MissingRegistrationReportingMode=Warn
选项,以查找代码中所有出现缺失注册的位置。在 GraalVM for JDK 23 中,
-XX:MissingRegistrationReportingMode=
被提升为运行时选项。在 JDK 23 之前的 GraalVM 版本中,请改用-H:MissingRegistrationReportingMode=Warn
构建选项。 -
如果报告了缺失的元数据,请务必将其添加到 reachability-metadata.json 文件中。请参阅 可达性元数据文档,了解如何操作。
并非总是需要将所有报告的元素都添加到 reachability-metadata.json 中。导致程序失败的通常是列表中最后几个。
在 JDK 23 之前的 GraalVM 版本中,可能会报告 reachability-metadata.json 中已存在的元素的错误。这些错误可以安全地忽略,因为它们是由
-H:ThrowMissingRegistrationErrors=
选项的实验性性质引起的。
共享库
要诊断使用 Native Image 构建的共享库,您可以选择
- 在构建本机共享库时指定
-R:MissingRegistrationReportingMode=Exit
; - 或在创建隔离区时指定
-XX:MissingRegistrationReportingMode=Exit
。graal_create_isolate_params_t
具有argc (_reserved_1)
和argv (_reserved_2)
字段,可用于在运行时传递 C 风格的命令行选项。但是,请注意,这两个字段目前都不是公共 API。
2. 显式设置 java.home
如果您的应用程序代码使用 java.home
属性,请在运行本机可执行文件时使用 -Djava.home=<path>
显式设置它。否则,System.getProperty("java.home")
调用将返回 null
值。
3. 启用 URL 协议
尝试在构建时按需启用所有 URL 协议:--enable-url-protocols=<protocols>
。若仅启用 HTTPS 支持,请传递 --enable-https
。
4. 启用信号处理
如果您的应用程序正在使用信号处理或 java.lang.Terminator
退出处理程序,请在构建时提供 --install-exit-handlers
选项。
5. 包含所有字符集和区域设置
其他便捷选项包括 -H:+AddAllCharsets
用于添加字符集支持,以及 -H:+IncludeAllLocales
用于预初始化 java.util
和 java.text
包中与区域设置相关的行为支持。在构建时传递这些选项。这可能会增加生成的二进制文件的大小。
6. 添加缺失的安全提供程序
如果您的应用程序使用安全提供程序,请尝试在构建时传递选项 -H:AdditionalSecurityProviders=<list-of-providers>
以预初始化安全提供程序。以下是所有可供选择的 JDK 安全提供程序列表:sun.security.provider.Sun,sun.security.rsa.SunRsaSign,sun.security.ec.SunEC,sun.security.ssl.SunJSSE,com.sun.crypto.provider.SunJCE,sun.security.jgss.SunProvider,com.sun.security.sasl.Provider,org.jcp.xml.dsig.internal.dom.XMLDSigRI,sun.security.smartcardio.SunPCSC,sun.security.provider.certpath.ldap.JdkLDAP,com.sun.security.sasl.gsskerb.JdkSASL
。
7. 提交 Native Image 运行时问题
只有在尝试了所有上述建议后,才在 GitHub 上提交 Native Image 运行时问题报告,并填写必要信息。
为了收集提交正确且可操作的工单所需的信息,建议在启用诊断模式的情况下运行 native-image
构建。传递 --diagnostics-mode
选项以启用类初始化、替换等诊断输出。