ネイティブ・イメージ・ランタイム・エラーのトラブルシューティング

Ahead-of-Timeコンパイルが成功しても、実行時にクラッシュしたり、アプリケーションがJava VM上で動作するのと同じように動作しないイメージが生成されることがあります。このガイドでは、問題の診断および解決のための戦略とともに、そのいくつかの理由を示します。

GraalVMの最新バージョンにアップグレードすると、問題を解決できる場合があることに注意してください。

1. 欠落しているメタデータ登録の診断

まず、欠落しているメタデータ構成があるかどうかを診断します。ネイティブ・イメージでは、使用されているすべてのクラスがビルド中に認識される必要があります。静的分析では、アプリケーションの実行時動作に関する予測が試行されます。場合によっては、すべての動的機能コールが認識されるように、分析に構成を提供する必要があります。そうしない場合、アプリケーションで動的機能が使用されると、診断が困難なエラーが発生して実行時にイメージが終了します。これは、欠落しているメタデータを慎重にチェックすることで回避できます。

  1. --exact-reachability-metadataオプションをnative-imageツールに渡し、アプリケーションを再ビルドします。特定のパッケージに対してのみこれを実行する場合は、パッケージ接頭辞--exact-reachability-metadata=[package prefix]を指定します。

    このオプションは、デバッグ目的でJDK 23用のGraalVMで導入されました。JDK 23より前のGraalVMバージョンでは、かわりに-H:ThrowMissingRegistrationErrors=ビルド・オプションを使用します。

  2. -XX:MissingRegistrationReportingMode=Warnオプションを渡して生成されたネイティブ実行可能ファイルを実行し、登録の欠落が発生しているコード内のすべての場所を検索します。

    -XX:MissingRegistrationReportingMode=は、GraalVM for JDK 23でランタイム・オプションに昇格されました。JDK 23より前のGraalVMバージョンでは、かわりに-H:MissingRegistrationReportingMode=Warnビルド・オプションを使用します。

  3. 欠落しているメタデータが報告された場合は、それを必ずreachability-metadata.jsonファイルに追加してください。その実行方法は、到達可能性メタデータのドキュメントを参照してください。

    すべてのレポート済要素をreachability-metadata.jsonに追加する必要があるわけではありません。プログラムの失敗の原因は、通常、リストの最後に含まれます。

    JDK 23より前のGraalVMバージョンでは、reachability-metadata.jsonにすでに存在する要素に関するエラーが報告される場合があります。これらは、-H:ThrowMissingRegistrationErrors=オプションの実験的な性質から生じるため、無視してもかまいません。

共有ライブラリ

ネイティブ・イメージとともにビルドされた共有ライブラリの診断では、次のいずれかを実行できます:

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オプションを渡して、クラスの初期化、置換などで診断出力を有効にします。