ネイティブ・イメージ・ランタイム・エラーのトラブルシューティング
Ahead-of-Timeコンパイルが成功しても、実行時にクラッシュしたり、アプリケーションがJava VM上で動作するのと同じように動作しないイメージが生成されることがあります。このガイドでは、問題の診断および解決のための戦略とともに、そのいくつかの理由を示します。
GraalVMの最新バージョンにアップグレードすると、問題を解決できる場合があることに注意してください。
1. 欠落しているメタデータ登録の診断
まず、欠落しているメタデータ構成があるかどうかを診断します。ネイティブ・イメージでは、使用されているすべてのクラスがビルド中に認識される必要があります。静的分析では、アプリケーションの実行時動作に関する予測が試行されます。場合によっては、すべての動的機能コールが認識されるように、分析に構成を提供する必要があります。そうしない場合、アプリケーションで動的機能が使用されると、診断が困難なエラーが発生して実行時にイメージが終了します。これは、欠落しているメタデータを慎重にチェックすることで回避できます。
-
--exact-reachablity-metadata
オプションをnative-image
ツールに渡し、アプリケーションを再ビルドします。特定のパッケージに対してのみこれを実行する場合は、パッケージ接頭辞--exact-reachablity-metadata=[package prefix]
を指定します。このオプションは、GraalVM for JDK 23で導入され、次の機能リリースではデフォルトになります。これは、
-H:ThrowMissingRegistrationErrors=
ホスト・オプションと同等です。 -
次に、
-XX:MissingRegistrationReportingMode=Warn
オプションを渡してネイティブ実行可能ファイルを実行し、登録の欠落が発生しているコード内のすべての場所を検索します。 -
欠落しているメタデータが報告された場合は、それを必ずreachability-metadata.jsonファイルに追加してください。その実行方法は、到達可能性メタデータのドキュメントを参照してください。
-
次に、
-XX:MissingRegistrationReportingMode=Exit
を使用してネイティブ実行可能ファイルを再開し、アプリケーションが(catch (Throwable t)
ブロックで)登録の欠落エラーを誤って無視している場所を検出します。その後、アプリケーションはスタック・トレースとともにエラー・メッセージを無条件に出力し、即座に終了します。この動作は、すべてのメタデータが含まれることを保証するアプリケーション・テストの実行に最適です。
共有ライブラリ
ネイティブ・イメージとともにビルドされた共有ライブラリの診断では、次のいずれかを実行できます:
- ネイティブ共有ライブラリのビルド時に
-R:MissingRegistrationReportingMode=Exit
を指定します。 - または、分離の作成時に
-XX:MissingRegistrationReportingMode=Exit
を指定します。graal_create_isolate_params_t
には、実行時にCスタイルのコマンドライン・オプションを渡すために使用できるargc (_reserved_1)
およびargv (_reserved_2)
フィールドがあります。ただし、現在、両方のフィールドはパブリック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
や、java.util
およびjava.text
パッケージでのロケール依存動作のサポートを事前に初期化する-H:+IncludeAllLocales
があります。これらのオプションはビルド時に渡します。これにより、生成されるバイナリのサイズが増加する可能性があります。
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. ネイティブ・イメージの実行時の問題の提出
前述の提案をすべて試した場合にのみ、GitHubにネイティブ・イメージの実行時の問題のレポートを提出し、必要な情報を入力します。
適切でアクション可能なチケットを提出するために必要な情報を収集するには、診断モードを有効にしてnative-image
ビルドを実行することをお薦めします。--diagnostics-mode
オプションを渡して、クラスの初期化、置換などで診断出力を有効にします。