原文はこちら。
The original article was written by Lazar Mitrović (GraalVM team at Oracle Labs).
https://medium.com/graalvm/gradle-and-maven-plugins-for-native-image-with-initial-junit-testing-support-dde00a8caf0b
新しい公式GraalVM Native Image GradleプラグインとMavenプラグインのリリースをお知らせします。このプラグインは、GraalVM Native ImageをJVMエコシステムの一級市民にすることを目的としており、Javaアプリケーションを簡単にネイティブ実行ファイルとしてビルド、テスト、実行できるようになります。主要な新機能は、JUnit 5テストのネイティブサポートがすぐ使えるようになっている点です。
Native Image
https://www.graalvm.org/reference-manual/native-image/
JUnit 5
https://junit.org/junit5/
JUnitのネイティブサポートにより、JVMエコシステム内のライブラリは、GraalVM Native Imageでテストスイートを実行できます。統合テストにより、ライブラリの設定は常に最新の状態に保たれ、エンドユーザーがすぐに利用できるようになります。これは、Javaエコシステムのネイティブ対応に向けた最大のステップであると考えています。
完全な例や使用方法を説明するスクリプトは以下からご覧いただけます。
Example projects for usage of GraalVM Native Image plugins
https://github.com/graalvm/native-build-tools/tree/master/examples
説明用実行スクリプト
https://github.com/graalvm/native-build-tools/blob/master/common/scripts/testAll.sh
Native Testing: The Way You Are Used to It
適切な設定と、テスト対象のプロジェクトにネイティブ特有のコード(ビルド時の初期化、置換、プラグインなど)が含まれていない場合、JUnit 5 を使った Java コードのテストは、ネイティブ実行でも JVM とまったく同じ動作をするようになりました。これを実現するために、junit-platform-nativeのカスタム機能を実装しました。
JUnit Platform support for GraalVM Native Image
https://github.com/graalvm/native-build-tools/tree/master/common/junit-platform-native
この機能は、標準的なJVM testタスクの前回の実行時に検出されたテストをログに記録し、ネイティブコンパイルとリフレクションのために登録します。この情報に基づいて、すべてのテスト(およびそのメタデータ)を含む特別なテスト実行ファイルがビルドされ、対応するビルドツールタスクを使用する際に呼び出されます。
メタデータの収集は、 JVM testタスクの実行に依存します。これはテスト時間の増加を招くという短所がありますが、プロジェクトに不足するリフレクション構成を生成するために利用可能な、ユーザーがnative-image-agentの呼び出しを有効化するための適切なエントリーポイントを提供します。エージェントの起動は、テストメタデータの収集とは無関係、つまりテストメタデータは常に収集される点に注意が必要です。
Assisted Configuration of Native Image Builds
https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/#assisted-configuration-of-native-image-builds
将来的には、JVM
test実行への依存性を取り除くことに取り組む予定です。そのためには、dry runをサポートして個々のテストを実行しなくてもメタデータを収集できるように、テストフレームワークを変更する必要があります。
詳細については、MavenやGradleのプラグインのドキュメントを参照してください。
Native Image Maven plugin
https://github.com/graalvm/native-build-tools/blob/master/native-maven-plugin/README.md
Native Image Gradle plugin
https://github.com/graalvm/native-build-tools/blob/master/native-gradle-plugin/README.md
Gradle Plugin
既存のGradleプロジェクトにnative-gradle-pluginを追加するには、build.gradleのpluginsセクションに以下を追加するだけです。
| plugins { | |
| id 'org.graalvm.buildtools.native' version "0.9.0" // or a newer version | |
| } |
以下をsettings.gradleに追加することでも実現できます。
| pluginManagement { | |
| repositories { | |
| mavenCentral() | |
| gradlePluginPortal() | |
| } | |
| } |
(このプラグインが Gradle Plugin Portal に公開されると、この手順は不要になります)。
その後、nativeBuild設定ブロックを使ってイメージビルドの設定が可能です。
| nativeBuild { | |
| imageName = "my-app" | |
| mainClass = "org.test.Main" | |
| verbose = true | |
| fallback = false | |
| } |
その後、プラグインはメインクラスをビルドして実行するnativeBuildタスクとnativeRunタスクを追加します(予想通りかと思います☺)。ネイティブイメージのビルドにリフレクションの設定が必要な場合、ユーザーによる追加設定なしにnative-image-agentを有効にするシンプルなオプションもこのプラグインでは提供しています。より詳しい情報(およびKotlinの設定構文)は、ドキュメントに記載されています。
Assisted Configuration of Native Image Builds
https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/#assisted-configuration-of-native-image-builds
Native Image Gradle Plugin
https://github.com/graalvm/native-build-tools/blob/master/native-gradle-plugin/README.md
コミュニティの移行を容易にするために、現時点では、最も人気のある非公式GraalVM Gradleプラグイン(
io.micronaut.applicationとcom.palantir.graal)の設定構文とエイリアスタスク名のサブセットをサポートしています。この動作はいずれ非推奨になる可能性があるのでご注意ください。
Testing in Gradle
ユーザーはnativeTestタスクを起動して、ネイティブイメージのテストを始めることができます(nativeTest設定ブロックを使ってnative-imageの設定を追加することもできます)。
| $ ./gradlew nativeTest | |
| > Task :nativeTest | |
| JUnit Platform on Native Image - report | |
| ---------------------------------------- | |
| org.graalvm.buildtools.example.App2Test > appHasAGreeting() SUCCESSFUL | |
| org.graalvm.buildtools.example.AppTest > appHasAGreeting() SUCCESSFUL | |
| Test run finished after 3 ms | |
| [ 3 containers found ] | |
| [ 0 containers skipped ] | |
| [ 3 containers started ] | |
| [ 0 containers aborted ] | |
| [ 3 containers successful ] | |
| [ 0 containers failed ] | |
| [ 2 tests found ] | |
| [ 0 tests skipped ] | |
| [ 2 tests started ] | |
| [ 0 tests aborted ] | |
| [ 2 tests successful ] | |
| [ 0 tests failed ] | |
| BUILD SUCCESSFUL in 771ms | |
| 5 actionable tasks: 1 executed, 4 up-to-date |
ネイティブテストは、あらかじめJVMモードで標準の
testタスクを実行しておく必要があることに注意してください。
Maven Plugin
既存のプラグインを、新しい maven coordinates (org.graalvm.buildtools:native-maven-plugin)の下でリリースします。この変更は、プラグインの開発をGraalVMのリリースサイクルから切り離すことで、より迅速に進めることを意図しています。既存のnative-image-maven-pluginをお使いであれば、新プラグインは旧プラグインと後方互換性があるため、pom.xml中のプラグインのgroupId、artifactId、versionを変更するだけで済みます。新しいプラグインのバージョンは0.9.0から始まります。
既存のMavenプロジェクトに新しいプラグインを追加するには、pom.xmlに以下の内容を追加する必要があります。
| <profiles> | |
| <profile> | |
| <id>native</id> | |
| <build> | |
| <plugins> | |
| <plugin> | |
| <groupId>org.graalvm.buildtools</groupId> | |
| <artifactId>native-maven-plugin</artifactId> | |
| <version>0.9.0</version> <!-- or newer version --> | |
| <executions> | |
| <execution> | |
| <id>test-native</id> | |
| <goals> | |
| <goal>test</goal> | |
| </goals> | |
| <phase>test</phase> | |
| </execution> | |
| <execution> | |
| <id>build-native</id> | |
| <goals> | |
| <goal>build</goal> | |
| </goals> | |
| <phase>package</phase> | |
| </execution> | |
| </executions> | |
| <configuration> | |
| <imageName>my-app</imageName> | |
| <mainClass>org.test.Main</mainClass> | |
| <buildArgs> | |
| --no-fallback | |
| --verbose | |
| </buildArgs> | |
| </configuration> | |
| </plugin> | |
| </plugins> | |
| </build> | |
| </profile> | |
| </profiles> |
その後、以下を実行してネイティブイメージをビルドできます。
mvn -Pnative -DskipTests package
Testing in Maven
以下を実行してネイティブイメージをテストできます。
mvn -Pnative test
Mavenプラグインでは、現在、リスナーを有効にするために追加の手順が必要で、pom.xmlにorg.graalvm.buildtools:junit-platform-nativeへの依存関係を追加する必要があります。JUnit 5.8が登場すれば、この手順は必要なくなります。
Introduce a Unique ID tracking TestExecutionListener #2619
https://github.com/junit-team/junit5/issues/2619
ネイティブテストを行うには、あらかじめJVMモードで標準のtestタスクを実行しておく必要がある点に注意が必要です。
ドキュメントやその他の設定方法については以下をご覧ください。
Native Image Maven Plugin
https://github.com/graalvm/native-build-tools/blob/master/native-maven-plugin/README.md
Future Goals
レガシーライブラリのために自動的に追加される設定を備えた標準的なリポジトリを作成することを次のステップと考えています。これにより、Native Imageをサポートしていないライブラリであっても、Native Imageの開発がよりスムーズに行えるようになるはずです。エコシステムの大半にfirst partyサポートがもたらされるよう、コミュニティと密接に協力しながら、オリジナルライブラリのパッチやPRをフォローしていく予定です。
Native Image Build Configuration
https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/
Built with Love Through Collaboration
今回のテストサポートの件は、JUnit、Micronaut、Springの各チームと共同で開発しました。Sam Brannen、Graeme Rocher、Sébastien Deleuzeの貢献とアドバイスに感謝します。この新プラグインはすでにSpring Native 0.10.0に搭載されており、すぐに多くのプロジェクトが追随することを期待しています。
JUnit 5
https://junit.org/junit5/
Micronaut Framework
https://micronaut.io/
Spring
https://spring.io/
Spring Native
https://github.com/spring-projects-experimental/spring-native
みなさまの経験や潜在的な問題についてお聞きしたいと思っています。コントリビューションも大歓迎です。
プロジェクトのリポジトリは以下からどうぞ。
Native Build Tools
https://github.com/graalvm/native-build-tools
ここで言及されているすべてのプロジェクトは、Universal Permissive Licenseの下でリリースされています。
Universal Permissive License (UPL), Version 1.0
https://www.oracle.com/downloads/licenses/upl-license1.html