◀返回
疑難排解 Native Image 執行階段錯誤
即使預先編譯成功,仍然可能產生在執行階段當機或行為與應用程式在 Java VM 上不同的映像檔。本指南將說明一些造成此現象的原因,以及診斷和解決問題的策略。
請注意,有時升級到最新版本的 GraalVM 即可解決問題。
1. 診斷遺失的中繼資料註冊
首先診斷是否有遺失的中繼資料設定。Native Image 要求在建置期間必須已知所有使用的類別。靜態分析會嘗試預測應用程式的執行階段行為。在某些情況下,您需要為分析提供設定,使其可見所有動態功能呼叫。若未如此,則會產生在執行階段因難以診斷的錯誤而終止的映像檔,一旦應用程式中使用動態功能就會發生。您可以透過積極檢查是否遺失中繼資料來避免此問題。
-
將
--exact-reachablity-metadata
選項傳遞至native-image
工具,然後重新建置應用程式。如果只想針對特定套件執行此動作,請指定套件字首--exact-reachablity-metadata=[套件字首]
。此選項已在適用於 JDK 23 的 GraalVM 中推出,並將在下一個功能版本中成為預設選項。它與
-H:ThrowMissingRegistrationErrors=
主機選項等效。 -
接著執行該原生可執行檔,並傳遞
-XX:MissingRegistrationReportingMode=Warn
選項,以找出程式碼中發生遺失註冊的所有位置。 -
如果回報遺失某些中繼資料,請務必將其新增至 reachability-metadata.json 檔案。請參閱可及性中繼資料文件,瞭解如何執行此操作。
-
然後以
-XX:MissingRegistrationReportingMode=Exit
重新啟動原生可執行檔,以偵測應用程式意外忽略遺失註冊錯誤的位置(使用catch (Throwable t)
區塊)。接著應用程式會無條件地列印錯誤訊息和堆疊追蹤,並立即結束。此行為非常適合執行應用程式測試,以確保所有中繼資料都已包含在內。
共用程式庫
對於使用 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=<路徑>
明確設定。否則,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.util
和 java.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
選項,針對類別初始化、取代等等啟用診斷輸出。