ネイティブ・イメージ・ビルド構成
- 構成ファイルの埋込み
- 構成ファイルの形式
- ネイティブ・イメージ・ビルドのメモリー構成
- 実行時とビルド時の初期化
- ネイティブ・イメージ・ビルドの構成支援
- 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
に配置できる任意の計算がビルド時に許可されます。詳細は、ネイティブ・イメージの構成例を参照してください。
詳細は、この後の「ネイティブ・イメージのクラスの初期化」も参照してください。