ネイティブ・イメージ・ビルド構成
ネイティブ・イメージでは、native-image
ビルダーを構成する様々なオプションがサポートされています。
目次
構成ファイルの埋込み
native-image.propertiesファイルをプロジェクトJARファイルに埋め込むことで、native-image
ビルダーの構成を指定することをお薦めします。また、native-image
ビルダーは、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:ResourceConfigurationResources=${.}/custom_resources.json
など)を参照する場合に役立ちます。常に、リソースを取得するオプション・バリアントを使用してください。つまり、-H:ResourceConfigurationFiles
のかわりに-H:ResourceConfigurationResources
を使用します。このコンテキストで動作するその他のオプションは次のとおりです:
-H:DynamicProxyConfigurationResources
-H:JNIConfigurationResources
-H:ReflectionConfigurationResources
-H:ResourceConfigurationResources
-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ファイルは、native-image
の構成を指定する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
native-image
ビルダーを実行する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
を生成します
デフォルトの構成ディレクトリの変更
ネイティブ・イメージでは、デフォルトでユーザーのホーム・ディレクトリ($HOME/.native-image/)に構成情報が格納されます。このデフォルトを変更するには、環境変数NATIVE_IMAGE_USER_HOME
を別の場所に設定します。たとえば:
export NATIVE_IMAGE_USER_HOME= $HOME/.local/share/native-image
引数の評価の順序
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
ツールでは、呼出しごとにそこで定義されたデフォルト設定が使用されます。
構成ファイルを書き込み、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
ネイティブ・イメージ・ビルドのメモリー構成
native-image
ビルダーはJVMで実行され、基礎となるプラットフォームのメモリー管理を使用します。ガベージ・コレクションの通常のJavaコマンドライン・オプションは、native-image
ビルダーに適用されます。
ネイティブ実行可能ファイルの作成時に、アプリケーション全体の表現が作成され、実行時にどのクラスおよびメソッドを使用するかが決定されます。これは、メモリー使用量に対して次のデフォルト値を使用する、計算量が多いプロセスです:
-Xss10M \
-Xms1G \
これらのデフォルト値は、native-image
ツールに-J + <jvm option for memory>
を渡すことで変更できます。
-Xmx
値は物理メモリー・サイズの80%を使用して計算されますが、ホスト当たり14Gを超えることはありません。コマンドラインで-Xmx
に大きい値(-J-Xmx26G
など)を指定できます。
デフォルトでは、native-image
ツールは最大32個のスレッドを使用します(ただし、使用可能なプロセッサ数を超えることはありません)。カスタム値の場合、オプション-H:NumberOfThreads=...
を使用します。
native-image
ツールで使用可能なその他の関連オプションについては、コマンドnative-image --expert-options-all
の出力を参照してください。
ビルド時に定義する必要があるタイプの指定
適切に構造化されているライブラリまたはアプリケーションは、ネイティブ・バイナリを単独でビルドする際に、Javaタイプ(すべての到達可能なJavaタイプはビルド時に完全に定義されます)のリンクを処理する必要があります。デフォルトの動作では、リンク・エラーが発生した場合は実行時にスローされます。ただし、ビルド時に完全にリンクする必要があるクラスを指定することで、不要なリンク・エラーを回避できます。そのためには、--link-at-build-time
オプションを使用します。オプションが適切なコンテキストで使用されている場合(次を参照)、クラスおよびパッケージを明示的にリストせずに、ビルド時にリンクするために必要なクラスを指定できます。これは、ライブラリが他のライブラリに対する悪影響を回避するために、独自のクラスのみを構成できるように設計されています。オプションをコマンドラインのnative-image
ツールに渡し、これをmodule-pathまたはクラスパスのnative-image.properties
ファイルに埋め込むことができます。
オプションの使用方法と場所に応じて、動作は異なります:
- 引数なしで
--link-at-build-time
を使用する場合、スコープ内のすべてのクラスを完全に定義する必要があります。コマンドラインで引数なしで使用すると、すべてのクラスが"link-at-build-time"クラスとして扱われます。module-pathのnative-image.properties
ファイルに引数を埋め込まずに使用する場合、モジュールのすべてのクラスは"link-at-build-time"クラスとして扱われます。クラスパスのnative-image.properties
ファイルに埋め込まれた--link-at-build-time
を使用すると、次のエラーがスローされます:Error: Using '--link-at-build-time' without args only allowed on module-path. 'META-INF/native-image/org.mylibrary/native-image.properties' in 'file:///home/test/myapp/MyLibrary.jar' not part of module-path.
- 引数に
--link-at-build-time
オプション(--link-at-build-time=foo.bar.Foobar,demo.myLibrary.Name,...
など)を使用する場合、引数は完全修飾クラス名またはパッケージ名である必要があります。module-pathまたはクラスパス(native-image.properties
ファイルに埋め込まれる)で使用する場合、同じJARファイルに定義されているクラスおよびパッケージのみを指定できます。クラスパスで使用されるライブラリのパッケージは、明示的にリストする必要があります。このプロセスを簡単にするには、@<prop-values-file>
構文を使用して、パッケージ・リスト(またはクラス・リスト)を個別のファイルに自動的に生成します。
もう1つの便利なオプションは--link-at-build-time-paths
で、ビルド時に他の方法で完全に定義する必要があるクラスを指定できます。このバリアントには、-p
(--module-path
)または-cp
(--class-path
)を介して渡される引数と同じタイプの引数が必要です:
--link-at-build-time-paths <class search path of directories and zip/jar files>
指定されたエントリは検索され、内部のすべてのクラスは--link-at-build-time
クラスとして登録されます。このオプションは、コマンドラインでのみ使用できます。