ネイティブ・イメージ
ネイティブ・イメージは、Javaコードをバイナリ(ネイティブ実行可能ファイル)に事前にコンパイルするテクノロジです。ネイティブ実行可能ファイルには、実行時に必要なコード、つまりアプリケーション・クラス、標準ライブラリ・クラス、言語ランタイム、およびJDKから静的にリンクされたネイティブ・コードのみが含まれます。
ネイティブ・イメージによって生成される実行可能ファイルには、いくつかの重要な利点があります
- Java仮想マシンに必要なリソースの一部を使用しているため、実行コストが低くなります
- ミリ秒単位で起動します
- ウォームアップなしで即座にピーク・パフォーマンスを実現します
- 軽量のコンテナ・イメージにパッケージ化して、迅速かつ効率的に導入できます
- 攻撃対象領域が縮小されます
ネイティブ実行可能ファイルは、アプリケーション・クラスを処理するネイティブ・イメージ・ビルダーまたはnative-image
によって作成され、その他のメタデータによって特定のオペレーティング・システムおよびアーキテクチャのバイナリが作成されます。まず、native-image
ツールはコードの静的分析を実行して、アプリケーションの実行時にアクセス可能なクラスおよびメソッドを決定します。次に、クラス、メソッドおよびリソースをバイナリにコンパイルします。このプロセス全体は、Javaソース・コードからバイトコードへのコンパイルと明確に区別するために、ビルド時と呼ばれます。
native-image
ツールを使用して、ネイティブ実行可能ファイル(デフォルト)またはネイティブ共有ライブラリをビルドできます。このクイック・スタート・ガイドでは、ネイティブ実行可能ファイルのビルドに重点を置いています。ネイティブ共有ライブラリの詳細は、こちらを参照してください。
ネイティブ・イメージの用語に慣れてテクノロジの理解を深めるには、ネイティブ・イメージの基本を読むことをお薦めします。
目次
前提条件
GraalVMインストールのbin
ディレクトリで使用可能なnative-image
ツールは、ローカル・ツールチェーン(Cライブラリ、glibc-devel
、zlib
、gcc
またはlibstdc++-static
(あるいはそのすべて)のヘッダー・ファイル)に依存します。これらの依存性は、マシン上のパッケージ・マネージャを使用してインストールできます(まだインストールされていない場合)。ご使用のオペレーティング・システムを選択して、前提条件を満たすための手順を確認します。
ネイティブ実行可能ファイルのビルド
native-image
ツールは、入力としてJavaバイトコードを使用します。ネイティブ実行可能ファイルは、クラス・ファイルから、JARファイルから、またはモジュールから(Java 9以上を使用)ビルドできます。
クラスから
現在の作業ディレクトリ内のJavaクラス・ファイルからネイティブ実行可能ファイルをビルドするには、次のコマンドを使用します:
native-image [options] class [imagename] [options]
たとえば、HelloWorldアプリケーションのネイティブ実行可能ファイルをビルドします。
- このコードをHelloWorld.javaという名前のファイルに保存します:
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, Native World!"); } }
- コンパイルして、Javaクラスからネイティブ実行可能ファイルをビルドします:
javac HelloWorld.java native-image HelloWorld
現在の作業ディレクトリにネイティブ実行可能ファイル
helloworld
が作成されます。 -
アプリケーションを実行します:
./helloworld
使用されているリソースが表示されるまで時間がかかります:
time -f 'Elapsed Time: %e s Max RSS: %M KB' ./helloworld # Hello, Native World! # Elapsed Time: 0.00 s Max RSS: 7620 KB
JARファイルから
現在の作業ディレクトリ内のJARファイルからネイティブ実行可能ファイルをビルドするには、次のコマンドを使用します:
native-image [options] -jar jarfile [imagename]
native-image
のデフォルトの動作は、java
コマンドと一致しています。これは、java
で通常行うように、-jar
、-cp
、-m
オプションを渡してネイティブ・イメージでビルドできることを意味します。たとえば、java -jar App.jar someArgument
はnative-image -jar App.jar
および./App someArgument
になります。
JARファイルからネイティブ実行可能ファイルをビルドするには、このガイドに従います。
モジュールから
モジュール化されたJavaアプリケーションをネイティブ実行可能ファイルに変換することもできます。
Javaモジュールからネイティブ実行可能ファイルをビルドするコマンドは次のとおりです:
native-image [options] --module <module>[/<mainclass>] [options]
モジュラJavaアプリケーションからネイティブ実行可能ファイルを生成する方法の詳細は、ネイティブ実行可能ファイルへのHelloWorld Javaモジュールのビルドに関する項を参照してください。
ビルド・プロセスの完了時の通知の受信
アプリケーションのサイズおよびビルド・マシンで使用可能なリソースによっては、Javaアプリケーションをネイティブ実行可能ファイルにAOTコンパイルするのに数分かかる場合があります。プロジェクトをバックグラウンドでビルドする場合は、ビルド・プロセスの完了時に通知するコマンドを使用することを検討してください。次に、オペレーティング・システムごとにコマンドの例を示します:
Linux
# Ring the terminal bell
native-image -jar App.jar ... ; printf '\a'
# Use libnotify to create a desktop notification
native-image -jar App.jar ... ; notify-send "GraalVM Native Image build completed with exit code $?"
# Use Zenity to open an info dialog box with text
native-image -jar App.jar ... ; zenity --info --text="GraalVM Native Image build completed with exit code $?"
macOS
# Ring the terminal bell
native-image -jar App.jar ... ; printf '\a'
# Use Speech Synthesis
native-image -jar App.jar ... ; say "GraalVM Native Image build completed"
Windows
# Ring the terminal bell (press Ctrl+G to enter ^G)
native-image.exe -jar App.jar & echo ^G
# Open an info dialog box with text
native-image.exe -jar App.jar & msg "%username%" GraalVM Native Image build completed
ビルド構成
native-image
ビルダーに渡してビルド・プロセスを構成できるオプションが多数あります。native-image --help
を実行して、完全なリストを表示します。native-image
に渡されるオプションは左から右に評価されます。
様々なビルドの微調整およびビルド時の構成の詳細は、「ネイティブ・イメージ・ビルド構成」を参照してください。
ネイティブ・イメージは、ビルド中に進行状況および様々な統計を出力します。出力および様々なビルド・フェーズについてさらに学習するには、ビルド出力を参照してください。
ネイティブ・イメージおよびサードパーティ・ライブラリ
外部ライブラリを使用するより複雑なアプリケーションの場合は、native-image
ビルダーにメタデータを指定する必要があります。
native-image
ツールを使用したスタンドアロン・バイナリのビルドは、「閉世界仮説」の下で行われます。native-image
ツールは分析を実行して、アプリケーション内のどのクラス、メソッドおよびフィールドにアクセス可能であり、ネイティブ・イメージに含める必要があるかを確認します。分析は静的であり、アプリケーションを実行しません。つまり、実行時にコールできるアプリケーション内のすべてのバイトコードは、ビルド時に認識(監視および分析)される必要があります。
分析では、動的クラス・ロードのいくつかのケースを判断できますが、Java Native Interface (JNI)、Javaリフレクション、動的プロキシ・オブジェクトまたはクラスパス・リソースのすべての使用状況を常に完全に予測できるわけではありません。Javaのこれらの動的機能を処理するには、リフレクション、プロキシなどを使用するクラスの詳細、または動的にロードされるクラスについて分析に通知します。これを実現するには、native-image
ツールにJSON形式の構成ファイルまたはコード内の事前計算メタデータを指定します。
メタデータ、その指定方法およびサポートされているメタデータ・タイプについてさらに学習するには、到達可能性メタデータを参照してください。アプリケーションのメタデータを自動的に収集するには、メタデータの自動収集に関する項を参照してください。
ネイティブ・イメージ用のMavenおよびGradleプラグインもあり、ネイティブ実行可能ファイルのビルド、テストおよび構成を自動化します。詳細は、こちらを参照してください。
一部のアプリケーションでは、GraalVMネイティブ・イメージを使用してコンパイルするための追加構成が必要な場合があります。詳細は、ネイティブ・イメージの互換性ガイドを参照してください。
ネイティブ・イメージは、カスタムAPIを介してネイティブ言語と相互運用することもできます。このAPIを使用して、Javaアプリケーションへのカスタム・ネイティブ・エントリ・ポイントを指定し、それをnativw共有ライブラリにビルドできます。さらに学習するには、ネイティブ・コードとの相互運用性を参照してください。
その他の情報
このスタート・ガイドは、新しいユーザーまたはGraalVMネイティブ・イメージの使用経験がほとんどないユーザーを対象としています。このようなユーザーは、ネイティブ・イメージの基本を確認して、いくつかの重要な側面をよく理解してから詳細に進むことを強くお薦めします。
ユーザー・ガイドをチェックして、GraalVMネイティブ・イメージの使用経験を深め、デモの例を見つけ、潜在的な使用シナリオについて学習します。
段階的な学習プロセスについては、ネイティブ・イメージのビルドの概要およびビルド構成のドキュメントを確認してください。
実践的な経験を得るために対話型ワークショップを実行することを検討してください。Lunaラボに移動し、「ネイティブ・イメージ」を検索します。
考えられるバグを見つけた場合は、GitHubで問題を送信してください。
ネイティブ・イメージにコントリビュートする場合は、標準のコントリビュートのワークフローに従ってください。