返回

疑難排解 Native Image 執行階段錯誤

即使預先編譯成功,仍然可能產生在執行階段當機或行為與應用程式在 Java VM 上不同的映像檔。本指南將說明一些造成此現象的原因,以及診斷和解決問題的策略。

請注意,有時升級到最新版本的 GraalVM 即可解決問題。

1. 診斷遺失的中繼資料註冊

首先診斷是否有遺失的中繼資料設定。Native Image 要求在建置期間必須已知所有使用的類別。靜態分析會嘗試預測應用程式的執行階段行為。在某些情況下,您需要為分析提供設定,使其可見所有動態功能呼叫。若未如此,則會產生在執行階段因難以診斷的錯誤而終止的映像檔,一旦應用程式中使用動態功能就會發生。您可以透過積極檢查是否遺失中繼資料來避免此問題。

  1. --exact-reachablity-metadata 選項傳遞至 native-image 工具,然後重新建置應用程式。如果只想針對特定套件執行此動作,請指定套件字首 --exact-reachablity-metadata=[套件字首]

    此選項已在適用於 JDK 23 的 GraalVM 中推出,並將在下一個功能版本中成為預設選項。它與 -H:ThrowMissingRegistrationErrors= 主機選項等效。

  2. 接著執行該原生可執行檔,並傳遞 -XX:MissingRegistrationReportingMode=Warn 選項,以找出程式碼中發生遺失註冊的所有位置。

  3. 如果回報遺失某些中繼資料,請務必將其新增至 reachability-metadata.json 檔案。請參閱可及性中繼資料文件,瞭解如何執行此操作。

  4. 然後以 -XX:MissingRegistrationReportingMode=Exit 重新啟動原生可執行檔,以偵測應用程式意外忽略遺失註冊錯誤的位置(使用 catch (Throwable t) 區塊)。接著應用程式會無條件地列印錯誤訊息和堆疊追蹤,並立即結束。此行為非常適合執行應用程式測試,以確保所有中繼資料都已包含在內。

共用程式庫

對於使用 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=<路徑> 明確設定。否則,System.getProperty("java.home") 呼叫會傳回 null 值。

3. 啟用 URL 通訊協定

嘗試在建置時依需求啟用所有 URL 通訊協定:--enable-url-protocols=<通訊協定>。若只要啟用 HTTPS 支援,請傳遞 --enable-https

4. 啟用訊號處理

如果您的應用程式使用訊號處理或 java.lang.Terminator 結束處理常式,請在建置時提供 --install-exit-handlers 選項。

5. 包含所有字元集和地區設定

其他方便的選項包括 -H:+AddAllCharsets 新增字元集支援,以及 -H:+IncludeAllLocales 預先初始化 java.utiljava.text 套件中地區設定相關行為的支援。請在建置時傳遞這些選項。這可能會增加產生的二進位檔大小。

6. 新增遺失的安全提供者

如果您的應用程式使用安全提供者,請嘗試在建置時傳遞選項 -H:AdditionalSecurityProviders=<提供者清單> 來預先初始化安全提供者。以下是可供選擇的所有 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 選項,針對類別初始化、取代等等啟用診斷輸出。

與我們聯絡