ネイティブイメージビルド設定

ネイティブイメージは、native-imageビルダーを設定するための幅広いオプションをサポートしています。

目次 #

設定ファイルの埋め込み #

native-imageビルダーの設定は、native-image.propertiesファイルをプロジェクトJARファイルに埋め込むことをお勧めします。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にあります

foobarを含む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には、Args = --initialize-at-build-time=com.fasterxml.jackson.annotation.JsonProperty$Accessnative-image.propertiesファイルに含まれており、クラス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.barImageName=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ディレクトリの設定ファイルを通じて間接的に渡されるオプションにも適用されます。native-image.propertiesArgs = -H:Optimize=0が含まれているJARファイルの例を考えてみましょう。-cp <jar-file>の後に-H:Optimize=2オプションを使用することで、JARファイルに含まれている設定を上書きできます。

ネイティブイメージビルドのメモリ設定 #

native-imageビルダーはJVM上で実行され、基盤となるプラットフォームのメモリ管理を使用します。ガベージコレクションに関する通常のJavaコマンドラインオプションは、native-imageビルダーに適用されます。

ネイティブ実行ファイルの作成中は、アプリケーション全体の表現が作成され、実行時にどのクラスとメソッドが使用されるかが決定されます。これは計算集約的なプロセスであり、メモリ使用量には次のデフォルト値が使用されます。

-Xss10M \
-XX:MaxRAMPercentage=<percentage based on available memory> \
-XX:GCTimeRatio=19 \
-XX:+ExitOnOutOfMemoryError \

これらのデフォルト値は、native-imageツールに-J + <jvm option for memory>を渡すことで変更できます。

-XX:MaxRAMPercentage値はビルダーの最大ヒープサイズを決定し、システムの利用可能なメモリに基づいて計算されます。デフォルトでは最大32GBで、例えば、物理メモリの90%の場合は-J-XX:MaxRAMPercentage=90.0、4GBの場合は-Xmx4gを使用して上書きできます。-XX:GCTimeRatio=19は、ガベージコレクションの総時間目標を5%に増やし、スループットを重視し、ピークRSSを削減します。ビルドプロセスは、メモリ圧力の高い環境でより迅速なフィードバックを提供するために、最初のOutOfMemoryError-XX:+ExitOnOutOfMemoryError)で終了します。

デフォルトでは、native-imageツールは最大32スレッドを使用します(ただし、利用可能なプロセッサ数より多くはありません)。カスタム値を使用するには、--parallelism=...オプションを使用します。

native-imageツールで使用できるその他の関連オプションについては、コマンドnative-image --expert-options-allの出力を参照してください。

ビルド時に定義する必要がある型の指定 #

構造化されたライブラリまたはアプリケーションは、ネイティブバイナリを単独でビルドする場合、Java型のリンク処理(実行時に到達可能なすべてのJava型が完全に定義されていることを保証)を処理する必要があります。デフォルトの動作は、リンクエラーが発生した場合、実行時にエラーをスローすることです。ただし、ビルド時に完全にリンクする必要があるクラスを指定することで、予期しないリンクエラーを防ぐことができます。そのためには、--link-at-build-timeオプションを使用します。このオプションを適切なコンテキストで使用すると(下記参照)、クラスやパッケージを明示的にリストすることなく、ビルド時にリンクする必要があるクラスを指定できます。これは、ライブラリが他のライブラリへの副作用を回避するために、独自のクラスのみを設定できるよう設計されています。このオプションは、コマンドラインでnative-imageツールに渡すか、モジュールパスまたはクラスパス上のnative-image.propertiesファイルに埋め込むことができます。

引数なしで--link-at-build-timeを使用する場合、スコープ内のすべてのクラスが完全に定義されている必要があります。コマンドラインで引数なしで使用した場合、すべてのクラスが「link-at-build-time」クラスとして扱われます。モジュールパス上の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,...)、引数は完全修飾クラス名またはパッケージ名である必要があります。モジュールパスまたはクラスパス(native-image.propertiesファイルに埋め込まれている場合)で使用する場合、同じJARファイルで定義されているクラスとパッケージのみを指定できます。クラスパスで使用されるライブラリのpackagesは、明示的にリストする必要があります。このプロセスを容易にするために、@<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クラスとして登録されます。このオプションは、コマンドラインでのみ使用できます。

お問い合わせ