返回

排查 Native Image 运行时错误

即使预先编译成功,生成的映像仍可能在运行时崩溃,或者其行为与应用程序在 Java VM 上的行为不同。本指南将介绍一些导致此类问题的原因,并提供诊断和解决这些问题的策略。

请注意,有时升级到最新版本的 GraalVM 即可解决问题。

1. 诊断缺失的元数据注册

首先诊断是否存在任何缺失的元数据配置。Native Image 要求在构建期间已知所有已使用的类。静态分析会尝试预测应用程序的运行时行为。在某些情况下,您需要为分析提供配置,以便使其可见所有动态特性调用。如果未能这样做,一旦在应用程序中使用动态特性,生成的映像将在运行时终止,并出现难以诊断的错误。通过主动检查缺失的元数据可以避免这种情况。

  1. --exact-reachability-metadata 选项传递给 native-image 工具并重建应用程序。如果您只想针对特定包执行此操作,请指定包前缀 --exact-reachability-metadata=[package prefix]

    此选项在 GraalVM for JDK 23 中引入,用于调试。在 JDK 23 之前的 GraalVM 版本中,请改用 -H:ThrowMissingRegistrationErrors= 构建选项。

  2. 运行生成的本机可执行文件,并传递 -XX:MissingRegistrationReportingMode=Warn 选项,以查找代码中所有出现缺失注册的位置。

    在 GraalVM for JDK 23 中,-XX:MissingRegistrationReportingMode= 被提升为运行时选项。在 JDK 23 之前的 GraalVM 版本中,请改用 -H:MissingRegistrationReportingMode=Warn 构建选项。

  3. 如果报告了缺失的元数据,请务必将其添加到 reachability-metadata.json 文件中。请参阅 可达性元数据文档,了解如何操作。

    并非总是需要将所有报告的元素都添加到 reachability-metadata.json 中。导致程序失败的通常是列表中最后几个。

    在 JDK 23 之前的 GraalVM 版本中,可能会报告 reachability-metadata.json 中已存在的元素的错误。这些错误可以安全地忽略,因为它们是由 -H:ThrowMissingRegistrationErrors= 选项的实验性性质引起的。

共享库

要诊断使用 Native Image 构建的共享库,您可以选择

  • 在构建本机共享库时指定 -R:MissingRegistrationReportingMode=Exit
  • 或在创建隔离区时指定 -XX:MissingRegistrationReportingMode=Exitgraal_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.utiljava.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 选项以启用类初始化、替换等诊断输出。

联系我们