原文はこちら。
The original article was written by Stéphane Nicoll. (Spring Framework/Boot committer)
https://spring.io/blog/2022/09/26/native-support-in-spring-boot-3-0-0-m5
SpringチームはSpringアプリケーションのNative Imageサポートにかなり長い間取り組んできました。Spring Boot 2のSpring Native実験プロジェクトで3年以上インキュベーションした後、Native ImageのサポートはSpring Framework 6とSpring Boot 3で一般提供へ移行することになりました。
Spring Native
https://github.com/spring-projects-experimental/spring-native
Native Imageは、Javaアプリケーションの起動時間をほぼ瞬時にし、メモリ消費量を削減します。最近のSpring Boot 3.0.0-M5
リリースは、初めてNative Imageの話に関する幅広いコミュニティからのフィードバックを求めたものです。基本的なことをキャッチアップする必要がある場合は、3月下旬のInitial AOT support in Spring Framework 6.0.0-M3というブログエントリを参照してください。Spring Boot 3.0用にアプリケーションを準備する方法についても説明しています。
Initial AOT support in Spring Framework 6.0.0-M3
https://spring.io/blog/2022/03/22/initial-aot-support-in-spring-framework-6-0-0-m3
Preparing for Spring Boot 3.0
https://spring.io/blog/2022/05/24/preparing-for-spring-boot-3-0
3月以降、多くのことが起こりました。より多くのユースケースやライブラリとの互換性を向上させ、その過程でネイティブサポートを修正・改善しました。このブログエントリでは、Native Imageを使い始めるために知っておくべきことを詳しく説明します。
Building Your First Native Image
最も簡単な方法は、Spring Initializrから新しいプロジェクトを作成することです。
Spring Initializr
https://start.spring.io/
Spring Boot 3.0.0-M5(またはそれ以降)とお気に入りのビルドツールを選択していることを確認します。それができたら、Native Imageをビルドする1つの方法として、Native Build ToolsプラグインとローカルのGraalVMインストールを使用する方法があります。
Native Build Tools
https://graalvm.github.io/native-build-tools/latest/index.html
GraalVMをインストールする手順に従うか、またはSDKMan!がインストールされている場合は、以下を起動します。
Quick Start Guide
https://www.graalvm.org/java/quickstart/
$ sdk install java 22.2.r17-nik
native-image
ツールがPATH上にあることを確認することで、期待通りに動作していることを確認できます。Spring Bootには、MavenとGradleのための特別な統合があります。Mavenを使用している場合、ネイティブプロファイルを有効にすると、Native Imageをビルドするために必要なインフラストラクチャが起動します。
$ ./mvnw -Pnative package
Gradleの場合、プラグインはNative Build Toolsプラグインの存在に反応するので、それを適用する必要があります。
plugins {
..
id 'org.graalvm.buildtools.native' version '0.9.14'
}
これが完了したら、Native Imageをビルドするために必要なインフラを呼び出します。
$ /.gradlew nativeCompile
target/
と build/native/nativeCompile
にそれぞれローカル OS/CPU 用のネイティブバイナリが生成されます。他のバイナリと同様に、アプリを起動することができます。例えばMavenの場合です。
$ target/demo

Optimizing Applications at Build-Time
3.0では、ビルドプラグインにアプリケーションのahead-of-time処理を呼び出すするゴールが追加されました。このフェーズでは、アプリケーションは検査され、通常実行時に行う決定のいくつかが評価され、記録されます。
Spring Bootには多数の自動設定が同梱されていますが、これらは少なくともクラスパスの条件が一致するまで「休止状態」になります。Native Imageをビルドする場合、このような評価はNative Imageビルド前に行わなければならず、そうでなければすべての組み合わせがNative Imageに含まれてしまいます。
また、プロキシ、リフレクションやシリアライズの使用、リソースロードなど、GraalVMが推論できないユースケースを検出する必要もあります。この検出の結果、reachability metadata(到達性メタデータ)と呼ばれるものが形成されます。Springのポートフォリオ全体は、このようなユースケースを検出し、関連するメタデータを自動的に生成するように更新されました。
Javadocと閲覧しやすい構造を持つソースコードを生成することにしました。これにより、ビルド時に生成されたコードを検査し、必要に応じて簡単にデバッグすることができるようになりました。また、これはつまり結果的にnative-image
ツールには通常のコンパイルされたJava(アプリケーション)しか供給されないということです。
Reachability Metadata Repository
ネイティブ互換のためには、各ライブラリが必要な到達性メタデータ・ヒントを出荷することが望ましいのですが、これは常に可能というわけではありません。最近、Oracle Labs はサードパーティの到達性メタデータのための共有リポジトリを発表しました。このリポジトリは、JVMエコシステム全体のための到達性メタデータを収集するために、貢献できるようオープンになっています。各エントリーは、さまざまなバージョンに対して分離してテストされます。
Enhancing 3rd-Party Library Support in GraalVM Native Image with Shared Metadata
https://medium.com/graalvm/enhancing-3rd-party-library-support-in-graalvm-native-image-with-shared-metadata-9eeae1651da4
https://logico-jp.io/2022/07/29/enhancing-3rd-party-library-support-in-graalvm-native-image-with-shared-metadata/
もしあなたのお気に入りのライブラリが必要なメタデータを提供していないのであれば、このリポジトリに貢献することを検討してください。Springチームは、私たちが提供するサードパーティライブラリの統合をベースにして、積極的に貢献しています。
Testing Support
Native Imageのサポートは、依存関係や構成に基づいてアプリケーションを最適化し、リフレクションやプロキシ処理などの必要性を推論することです。これにより、カスタムライブラリやフレームワークの使用など、あなたのアプリケーションに特有のものを見逃してしまう可能性があります。その手助けのために、このマイルストーンでは、既存のテストをNative Imageで実行する簡単な方法を提供し、アプリケーションとその依存関係が期待通りに動作することを確認できるようにします。
ネイティブ環境でテストスイートの実行は、Native Build Tools プラグインのテストサポートに依存します。まず、native-image
ツールがパスで利用可能であることを確認します(セットアップ方法は上記を参照ください)。
Mavenの場合、以下のように呼び出します。
$ ./mvnw -PnativeTest test
Gradleの場合のコマンドは以下のようです。
$ /.gradlew nativeTest
ApplicationContextを使用しているテストでは、これを最適化し、必要な到達性メタデータを推論する同じプロセスを適用します。
Your Application Does Not Work: Now What?
もし、あなたのアプリケーションがNative Imageとして動作しない場合、ぜひそのフィードバックをお寄せください。10月下旬に予定されているリリース候補までにサポートを改善したいと思います。エラーの内容によってサポートが異なります。
ahead-of-time最適化フェーズでのビルド失敗
Spring FrameworkのIssue trackerに報告してください。
Issues – spring-projects/spring-framework
https://github.com/spring-projects/spring-framework/issues
Native Image生成時のビルド失敗
様々な根本原因が考えられます。GitterやStackOverflowなど、通常のサポートチャンネルをご利用ください。
アプリケーションのビルドに成功したが、起動に失敗した場合
到達可能性メタデータが不足している可能性があります。そのメタデータの必要性は、あなた自身のコード由来の場合も、サードパーティライブラリ由来の場合もあります。
Spring Framework 6には新しいAPIが同梱されており、プログラムでヒントを記録することができます。もし足りないヒントがあなた自身のコードから来るものであれば、RuntimeHintsRegistrarの実装を検討してください。
RuntimeHintsRegistrar (Spring Framework 6.0.0-M6 API)
https://docs.spring.io/spring-framework/docs/6.0.0-M6/javadoc-api/org/springframework/aot/hint/RuntimeHintsRegistrar.html
具体的な例として、以下のサンプルアプリケーションをご覧ください。
snicoll/demo-aot-native: Demo of a basic webapp using Ahead-Of-Time compilation
https://github.com/snicoll/demo-aot-native
Next Steps
コミュニティからのフィードバックに基づき、AOT エンジンの改良を続け、今回導入した新しい API の詳細を提供するためにリファレンスガイドを更新していきます。今年11月にはGAの予定です。
これは、私たちにとってエキサイティングな時間です。すでにフィードバックをお寄せいただいた皆様に、改めて感謝申し上げます。