試験段階のエージェント・オプション
native-image-agent
ツールには、現在試験段階のオプションがあり、将来のリリースで有効になっている可能性がありますが、すべて変更または削除される可能性もあります。ここでは、これらのオプションについて説明します。
事前定義済クラスのサポート
ネイティブ・イメージでは、すべてのクラスをイメージのビルド時に認識する必要があります(閉世界仮説)。ただし、Javaでは、実行時の新しいクラスのロードをサポートしています。クラス・ロードをエミュレートするために、動的にロードされたクラスをトレースし、後でイメージ・ビルダーで使用できるようにバイトコードを保存するように、エージェントに指示できます。この機能は、experimental-class-define-support
をエージェント・オプション文字列に追加することで有効にできます。例: -agentlib:native-image-agent=config-output-dir=config,experimental-class-define-support
。標準構成ファイルとは別に、エージェントは構成出力ディレクトリにagent-extracted-predefined-classes
ディレクトリを作成し、新しくロードされたクラスのバイトコードをそこに書き込みます。構成ディレクトリは、追加の微調整なしでイメージ・ビルダーで使用できます。クラスはイメージのビルド中にロードされますが、初期化されず、アプリケーションで使用可能になりません。実行時に、トレース中に検出されたクラスの1つと同じ名前およびバイトコードを持つクラスをロードしようとすると、事前定義済のクラスがアプリケーションに提供されます。
既知の制限事項
- ネイティブ・イメージでは、1つのクラス・ローダーによる、実行当たり1回のみの事前定義クラスのロードがサポートされています。
- 事前定義済クラスは、実行時にロードされると初期化され、ビルド時に初期化されることはありません。
- エージェントは、Java VMの組込みクラス・ローダー(例外あり)のいずれかによってロードされていない、つまりクラス・パスまたはモジュール・パスからロードされていないすべてのクラスを収集します。これには、カスタム・クラス・ローダーによってロードされるクラスが含まれます。
- 連続番号や乱数やタイムスタンプなど、名前やバイトコードで様々なデータを使用して生成されるクラスは、通常、実行時に事前定義されたクラスとは一致しない場合があります。このような場合、このようなクラスの生成方法を調整する必要があります。
起点を使用した構成の印刷
デバッグには、特定の構成エントリの起点を把握しておくと便利です。エージェント・オプション文字列にexperimental-configuration-with-origins
を指定すると、エージェントは、起点となったコール元のコンテキスト(スタック・トレース)にツリー形式で構成エントリを分類して、構成ファイルを出力します。このオプションは、構成ファイルを出力する場所をエージェントに指示するために、config-output-dir=<path>
と組み合せて使用する必要があります。エージェント・オプション文字列の例: -agentlib:native-image-agent=config-output-dir=config-with-origins/,experimental-configuration-with-origins
エージェントの出力からの構成の省略
エージェントは、既存の構成ファイルに存在するトレースされた構成エントリを省略できます。これらの既存の構成ファイルを指定するには、次の2つの方法があります:
- クラス・パスまたはモジュール・パスから構成ファイルを使用する方法。
experimental-omit-config-from-classpath
がエージェント・オプション文字列に追加されると、実行中のアプリケーションのクラス・パスおよびモジュール・パスがMETA-INF/native-image/**/*.json
構成ファイルに対してスキャンされます。 config-to-omit=<path>
を使用して、エージェントを既存の構成ファイル・ディレクトリに明示的に指定する方法。
エージェントを使用した条件付き構成の生成
エージェントは、ヒューリスティックを使用して、ユーザー指定のクラスの到達可能性条件によって構成を生成できます。エージェントは構成元を追跡し、条件を自動的に推測しようとします。ユーザー・クラスは、エージェント・フィルタ・ファイルで指定されます(形式の詳細は、エージェントの詳細に関する項)を参照してください。さらに、結果の構成は、別のフィルタ・ファイルを使用してさらにフィルタできます。
現在、この機能は2つのモードをサポートしています:
- エージェントによる単一の実行で条件付き構成を生成します。
- エージェントとの複数の実行から条件付き構成を生成し、最後に収集されたデータをマージします。
エージェント実行時の条件付き構成の生成
このモードを有効にするには、エージェントのコマンドラインにexperimental-conditional-config-filter-file=<path>
を追加します(<path>
はエージェント・フィルタ・ファイルを指します)。このフィルタで含まれているとみなされるクラスは、ユーザー・コード・クラスとして指定されます。生成された構成をさらにフィルタするには、conditional-config-class-filter-file=<path>
を使用できます。<path>
はエージェント・フィルタ・ファイルへのパスです。
複数のエージェント実行からの条件付き構成の生成
条件付き構成は、アプリケーションの様々なコード・パスに到達する複数のエージェント実行から生成できます。各エージェント実行では、メタデータを含む構成が生成されます。その後、native-image-configure
を使用して、収集されたデータをマージし、条件付き構成を生成します。このモードでエージェントを実行するには、エージェントのコマンドラインにexperimental-conditional-config-part
を追加します。すべてのエージェントの実行が終了したら、次を呼び出して条件付き構成を生成できます:
native-image-configure generate-conditional --user-code-filter=<path-to-filter-file> --class-name-filter=<path-to-filter-file> --input-dir=<path-to-agent-run-output-1> --input-dir=<path-to-agent-run-ouput-2> ... --output-dir=<path-to-resulting-conditional-config>
説明:
--user-code-filter=<path-to-filter-file>
: ユーザー・クラスを指定するエージェント・フィルタ・ファイルへのパス- (オプション)
--class-name-filter=<path-to-filter-file>
: 生成された構成をさらにフィルタするエージェント・フィルタ・ファイルへのパス
基礎となるヒューリスティック
条件は、アプリケーションのコール・ツリーを使用して生成されます。ヒューリスティックは、次のように機能します:
- 一意の各メソッドについて、メソッドに対応するコール・ツリー内のすべてのノードのリストを作成します
- 各一意のメソッドについて、そのメソッドのツリー内に複数のコール・ノードがある場合:
- そのメソッドのすべてのコール・ノードで共通構成を検索します
- メソッドのコール・ノードごとに、これらのコール間で共通しない構成をコール元ノードに伝播します
- 反復によりコール・ツリーで何も変更しなくなるまで、2を繰り返します。
- 構成を含む各ノードについて、メソッドのクラスを条件として条件付き構成エントリを生成します。
このヒューリスティックの主な目的は、メソッドによってコール元(たとえば、Class.forName
コールをラップするメソッド)に応じて異なる構成エントリが作成される場所を検索することです。これは、異なる依存性によって構成を生成するコードに対してヒューリスティックが適切に機能しないことを意味します(たとえば、同じメソッドがシステム・プロパティに応じて異なるクラス・パラメータを使用してClass.forName
をコールします)。