ネイティブ・イメージ・ビルド構成
- 構成ファイルの埋込み
- 構成ファイルの形式
- ネイティブ・イメージ・ビルドのメモリー構成
- 実行時とビルド時の初期化
- ネイティブ・イメージ・ビルドの構成支援
- Javaリフレクションを使用したネイティブ・イメージのビルド例
- エージェントの高度な使用方法
ネイティブ・イメージでは、ネイティブ・イメージ・ビルド・プロセスを構成するための広範なオプションがサポートされています。
構成ファイルの埋込み
native-image.propertiesファイルをプロジェクトJARファイルに埋め込むことで構成を適用することをお薦めします。ネイティブ・イメージ・ビルダーは、リソースの場所META-INF/native-image/の下のすべての場所で指定されたすべての構成オプションを自動的に取得し、それを使用してnative-imageコマンドライン引数を構築します。
プロジェクトの構成要素が重複構成を使用してビルドされないように、META-INF/native-image内でサブディレクトリを使用することをお薦めします。これにより、複数のmavenプロジェクトからビルドされたJARファイルでnative-image構成が重複することがなくなります。たとえば:
- foo.jarの構成は、
META-INF/native-image/foo_groupID/foo_artifactIDに置きます - bar.jarの構成は、
META-INF/native-image/bar_groupID/bar_artifactIDに置きます
これにより、fooおよびbarを含むJARファイルには、相互に競合することなく両方の構成が含められます。したがって、ネイティブ・イメージ構成データをJARファイルに格納するレイアウトは次のようにすることをお薦めします:
META-INF/
└── native-image
└── groupID
└── artifactID
└── native-image.properties
native-image.propertiesファイルで${.}を使用すると、その正確な構成ファイルを含むリソースの場所に展開されます。これは、native-image.propertiesファイルでサブフォルダ内のリソースを参照する場合に便利です(-H:SubstitutionResources=${.}/substitutions.jsonなど)。常に、リソースを取得するオプション・バリアントを使用してください。つまり、-H:ResourceConfigurationFilesのかわりに-H:ResourceConfigurationResourcesを使用します。このコンテキストで動作することがわかっているその他のオプションは次のとおりです:
-H:DynamicProxyConfigurationResources-H:JNIConfigurationResources-H:ReflectionConfigurationResources-H:ResourceConfigurationResources-H:SubstitutionResources-H:SerializationConfigurationResources
このような構成可能なnative-image.propertiesファイルを使用することで、イメージをビルドする際にコマンドラインで追加の引数を指定する必要がなくなります。次のコマンドを実行するのみです:
$JAVA_HOME/bin/native-image -jar target/<name>.jar
イメージのビルドに適用される構成データをデバッグするには、native-image --verboseを使用します。これにより、native-imageがネイティブ・イメージ・ビルダーの最終的なコンポジット構成コマンドライン・オプションを構築するためにどこから構成を取得するかが示されます。
native-image --verbose -jar build/basic-app-0.1-all.jar
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/common/native-image.properties
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/buffer/native-image.properties
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/transport/native-image.properties
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/handler/native-image.properties
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/codec-http/native-image.properties
...
Executing [
<composite configuration command line options for the image builder>
]
META-INF/native-imageベースのネイティブ・イメージ構成の一般的な例は、ネイティブ・イメージの構成例を参照してください。
構成ファイルの形式
native-image.propertiesファイルは、ネイティブ・イメージ構成の指定に使用できる通常のJavaプロパティ・ファイルです。次のプロパティがサポートされています。
Args
プロジェクトでビルドを正しく行うためにカスタムのnative-imageコマンドライン・オプションが必要な場合は、このプロパティを使用します。たとえば、native-image-configure-examples/configure-at-runtime-exampleのnative-image.propertiesファイルには、イメージのビルド時にクラスcom.fasterxml.jackson.annotation.JsonProperty$Accessが初期化されるようにArgs = --initialize-at-build-time=com.fasterxml.jackson.annotation.JsonProperty$Accessが含まれています。
JavaArgs
ネイティブ・イメージ・ビルダーを実行するJVMにカスタム・オプションを渡す必要がある場合があります。この場合、JavaArgsプロパティを使用できます。
ImageName
このプロパティは、イメージのユーザー定義名を指定するために使用できます。ImageNameを使用しない場合、名前は自動的に選択されます:
native-image -jar <name.jar>には、デフォルトのイメージ名<name>がありますnative-image -cp ... fully.qualified.MainClassには、デフォルトのイメージ名fully.qualified.mainclassがあります
ImageNameを使用しても、ユーザーが後でコマンドラインから名前をオーバーライドできます。たとえば、foo.barにImageName=foo_appが含まれているとします:
native-image -jar foo.barでは、イメージfoo_appが生成されますnative-image -jar foo.bar applicationでは、イメージapplicationが生成されます
引数の評価の順序
native-imageに渡される引数は、左から右に評価されます。これは、META-INF/native-imageベースのネイティブ・イメージ構成を介して間接的に渡される引数にも当てはまります。Args = -H:Optimize=0が指定されたnative-image.propertiesを含むJARファイルがあるとします。この場合、-cp <jar-file>の後に-H:Optimize=2オプションを使用することで、JARファイルからの設定をオーバーライドできます。
ネイティブ・イメージのデフォルト・オプションの指定
すべてのイメージ・ビルドに対して無条件でいくつかのオプションを渡す必要がある場合(たとえば、常に冗長モード(--verbose)でイメージを生成する場合)、NATIVE_IMAGE_CONFIG_FILE環境変数を使用できます。Javaプロパティ・ファイルに設定されている場合、ネイティブ・イメージ・ビルダーでは、そこに定義されているデフォルト設定が各呼出しで使用されます。構成ファイルを書き込み、NATIVE_IMAGE_CONFIG_FILE=$HOME/.native-image/default.propertiesを~/.bash_profileにエクスポートします。native-imageが使用されるたびに、NativeImageArgsとして指定された引数、およびコマンドラインで指定された引数が暗黙的に使用されます。次に、~/.native-image/default.propertiesとして保存された構成ファイルの例を示します:
NativeImageArgs = --configurations-path /home/user/custom-image-configs \
-O1
構成ディレクトリの変更
ネイティブ・イメージでは、デフォルトではユーザーのホーム・ディレクトリ($HOME/.native-image/)に構成情報が格納されます。出力ディレクトリを変更するには、環境変数NATIVE_IMAGE_USER_HOMEを別の場所に設定します。たとえば:
export NATIVE_IMAGE_USER_HOME= $HOME/.local/share/native-image
ネイティブ・イメージ・ビルドのメモリー構成
ネイティブ・イメージ・ビルドはJava HotSpot VM上で実行され、そのとき、基礎となるプラットフォームのメモリー管理が使用されます。ガベージ・コレクション用の通常のJava HotSpotコマンドライン・オプションがネイティブ・イメージ・ビルダーに適用されます。
ネイティブ・イメージ・ビルドの過程で、実行時に使用されるクラスとメソッドがわかるようにプログラム全体の表現が作成されます。これは計算集中型のプロセスです。イメージのビルド時におけるメモリー使用量のデフォルト値は次のとおりです:
-Xss10M \
-Xms1G \
これらのデフォルト値は、ネイティブ・イメージ・ビルダーに-J + <jvm option for memory>を渡すことで変更できます。
-Xmx値は物理メモリー・サイズの80%を使用して計算されますが、サーバー当たり14Gを超えることはありません。コマンドラインでは-Xmxにより大きい値を指定できます(例: -J-Xmx26G)。
デフォルトでは、イメージのビルドに最大32スレッドが使用されます(ただし、使用可能なプロセッサの数を超えることはありません)。カスタム値には-H:NumberOfThreads=...を使用できます。
native-image --expert-options-allリストからネイティブ・イメージ・ビルダーのその他の関連オプションをチェックします。
実行時とビルド時の初期化
アプリケーションをネイティブ・イメージにビルドすると、イメージのビルド時にアプリケーションのどの部分を実行し、イメージの実行時にどの部分を実行するかを決定できます。
イメージをビルドするアプリケーションのすべてのクラス初期化コード(静的イニシャライザおよび静的フィールド初期化)は、デフォルトでイメージの実行時に実行されます。起動を高速化するために、イメージのビルド時にクラス初期化コードを実行できると便利な場合があります(たとえば、一部の静的フィールドが実行時に依存しないデータに初期化される場合)。これは、次のnative-imageオプションで制御できます:
--initialize-at-build-time=<comma-separated list of packages and classes>--initialize-at-run-time=<comma-separated list of packages and classes>
それに加えて、イメージの実行時にアクセス可能なImageSingletonsに配置できる任意の計算がビルド時に許可されます。詳細は、ネイティブ・イメージの構成例を参照してください。
詳細は、この後の「ネイティブ・イメージのクラスの初期化」も参照してください。