初めての GraalVM ネイティブアプリケーションの開発
Spring Boot ネイティブイメージアプリケーションを構築するには、主に次の 2 つのメソッドがあります。
Cloud Native Buildpacks の Spring Boot サポートを Paketo Java ネイティブイメージ buildpack (英語) と共に使用して、ネイティブ実行可能ファイルを含む軽量コンテナーを生成します。
GraalVM ネイティブビルドツールを使用してネイティブ実行可能ファイルを生成します。
新しいネイティブ Spring Boot プロジェクトを開始する最も簡単な方法は、start.spring.io に移動し、GraalVM Native Support 依存関係を追加してプロジェクトを生成することです。含まれている HELP.md ファイルは、開始するためのヒントを提供します。 |
サンプルアプリケーション
ネイティブイメージを作成するために使用できるサンプルアプリケーションが必要です。この目的には、初めての Spring Boot アプリケーションの開発セクションで説明されているシンプルな "Hello World!" Web アプリケーションで十分です。
要約すると、メインのアプリケーションコードは次のようになります。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class MyApplication {
@RequestMapping("/")
String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
このアプリケーションは、Spring MVC と組み込みの Tomcat を使用します。どちらも、GraalVM ネイティブイメージで動作することがテストおよび検証されています。
Buildpacks を使用したネイティブイメージの構築
Spring Boot は、Maven と Gradle の両方と Cloud Native Buildpacks (CNB) の統合、および Paketo Java ネイティブイメージ buildpack (英語) を使用して、ネイティブ実行可能ファイルを含む Docker イメージの構築をサポートします。つまり、コマンドを 1 つ入力するだけで、ローカルで実行されている Docker デーモンに適切なイメージをすばやく取り込むことができます。結果のイメージには JVM が含まれず、ネイティブイメージが静的にコンパイルされます。これにより、イメージのサイズが小さくなります。
イメージに使用される CNB ビルダーは paketobuildpacks/builder-jammy-java-tiny:latest です。フットプリントが小さく、攻撃対象領域が縮小されていますが、必要に応じて paketobuildpacks/builder-jammy-base:latest または paketobuildpacks/builder-jammy-full:latest を使用して、イメージでさらに多くのツールを利用できるようになります。 |
システム要件
Docker をインストールする必要があります。詳細については、Docker を入手 (英語) を参照してください。Linux を使用している場合は root 以外のユーザーを許可するように構成します (英語) 。
docker run hello-world (sudo なし)を実行して、Docker デーモンが期待どおりに到達可能であることを確認できます。詳細については、Maven または Gradle Spring Boot プラグインのドキュメントを確認してください。 |
macOS では、Docker に割り当てられたメモリを少なくとも 8GB に増やし、場合によっては CPU も追加することをお勧めします。詳細については、このスタックオーバーフローの回答 (英語) を参照してください。Microsoft Windows では、パフォーマンスを向上させるために Docker WSL2 バックエンド (英語) を有効にしてください。 |
Maven の使用
Maven を使用してネイティブイメージコンテナーを構築するには、pom.xml
ファイルで spring-boot-starter-parent
および org.graalvm.buildtools:native-maven-plugin
を使用するようにする必要があります。次のような <parent>
セクションが必要です。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.1</version>
</parent>
さらに、これを <build> <plugins>
セクションに含める必要があります。
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
spring-boot-starter-parent
は、ネイティブイメージを作成するために実行する必要がある実行を構成する native
プロファイルを宣言します。コマンドラインで -P
フラグを使用して、プロファイルをアクティブ化できます。
spring-boot-starter-parent を使用したくない場合は、Spring Boot のプラグインから process-aot ゴールの実行を構成し、Native Build Tools プラグインから add-reachability-metadata ゴールを構成する必要があります。 |
イメージをビルドするには、native
プロファイルをアクティブにして spring-boot:build-image
ゴールを実行します。
$ mvn -Pnative spring-boot:build-image
Gradle の使用
Spring Boot Gradle プラグインは、GraalVM Native Image プラグインが適用されると、AOT タスクを自動的に構成します。Gradle ビルドに org.graalvm.buildtools.native
を含む plugins
ブロックが含まれていることを確認する必要があります。
org.graalvm.buildtools.native
プラグインが適用されている限り、bootBuildImage
タスクは JVM ではなくネイティブイメージを生成します。以下を使用してタスクを実行できます。
$ gradle bootBuildImage
サンプルの実行
適切なビルドコマンドを実行すると、Docker イメージが利用可能になります。docker run
を使用してアプリケーションを開始できます。
$ docker run --rm -p 8080:8080 docker.io/library/myproject:0.0.1-SNAPSHOT
次のような出力が表示されます。
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v{version-spring-boot})
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 0.08 seconds (process running for 0.095)
起動時間はマシンごとに異なりますが、JVM で実行されている Spring Boot アプリケーションよりもはるかに高速です。 |
Web ブラウザーを localhost:8080
で開くと、次の出力が表示されるはずです。
Hello World!
アプリケーションを正常に終了するには、ctrl-c
を押します。
ネイティブビルドツールを使用したネイティブイメージのビルド
Docker を使用せずにネイティブ実行可能ファイルを直接生成する場合は、GraalVM Native Build Tools を使用できます。ネイティブビルドツールは、Maven と Gradle の両方に対して GraalVM が提供するプラグインです。使用して、ネイティブイメージの生成など、さまざまな GraalVM タスクを実行できます。
前提条件
ネイティブビルドツールを使用してネイティブイメージをビルドするには、マシンに GraalVM ディストリビューションが必要です。Liberica ネイティブイメージキットページ (英語) で手動でダウンロードするか、SDKMAN! などのダウンロードマネージャーを使用できます。
Linux と macOS
macOS または Linux にネイティブイメージコンパイラーをインストールするには、SDKMAN! を使用することをお勧めします。次のコマンドを使用して、sdkman.io (英語) から SDKMAN! を取得し、Liberica GraalVM ディストリビューションをインストールします。
$ sdk install java 22.3.r17-nik
$ sdk use java 22.3.r17-nik
java -version
の出力をチェックして、正しいバージョンが構成されていることを確認します。
$ java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode)
Windows
Windows では、次の手順 (英語) に従って、バージョン 22.3 の GraalVM (英語) または Liberica ネイティブイメージキット (英語) 、Visual Studio ビルドツール、および Windows SDK をインストールします。Windows 関連のコマンドラインの最大長 のため、Maven または Gradle プラグインを実行するには、通常の Windows コマンドラインではなく、必ず x64 ネイティブツールコマンドプロンプトを使用してください。
Maven の使用
buildpacks サポートと同様に、native
プロファイルを継承するために spring-boot-starter-parent
を使用していること、および org.graalvm.buildtools:native-maven-plugin
プラグインが使用されていることを確認する必要があります。
native
プロファイルがアクティブな状態で、native:compile
ゴールを呼び出して native-image
コンパイルをトリガーできます。
$ mvn -Pnative native:compile
ネイティブイメージの実行可能ファイルは、target
ディレクトリにあります。
Gradle の使用
Native Build Tools Gradle プラグインがプロジェクトに適用されると、Spring Boot Gradle プラグインが Spring AOT エンジンを自動的にトリガーします。タスクの依存関係は自動的に構成されるため、標準の nativeCompile
タスクを実行するだけでネイティブイメージを生成できます。
$ gradle nativeCompile
ネイティブイメージの実行可能ファイルは、build/native/nativeCompile
ディレクトリにあります。
サンプルの実行
この時点で、アプリケーションは機能するはずです。アプリケーションを直接実行して開始できるようになりました。
Maven
Gradle
$ target/myproject
$ build/native/nativeCompile/myproject
次のような出力が表示されます。
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.1)
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 0.08 seconds (process running for 0.095)
起動時間はマシンごとに異なりますが、JVM で実行されている Spring Boot アプリケーションよりもはるかに高速です。 |
Web ブラウザーを localhost:8080
で開くと、次の出力が表示されるはずです。
Hello World!
アプリケーションを正常に終了するには、ctrl-c
を押します。