- はじめに
- Gradle のツールチェーンでプロビジョニングした GraalVM はシンボリックリンクが壊れている
- Native Image Plugin(0.9.25)は、Gradle 8.3 では動かない
- Native Image Plugin のトレースエージェントは GRAALVM_HOME / JAVA_HOME が必須
はじめに
macOS 上の Gradle で GraalVM ネイティブイメージを作成する際のハマりポイントを記しておきます。
Gradle プラグインは Graal 公式のもので、バージョン 0.9.25 です。
Native Image 自体もそうだけど、プラグインもまだまだ途上です。
Gradle のツールチェーンでプロビジョニングした GraalVM はシンボリックリンクが壊れている
settings.gradle.kts
は以下のように定義。
pluginManagement { repositories { mavenCentral() gradlePluginPortal() } } plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" } rootProject.name = "example" include("app")
build.gradle.kts
にてツールチェーンに JvmVendorSpec.GRAAL_VM
を指定。
plugins { application id("org.graalvm.buildtools.native") version "0.9.25" } repositories { mavenCentral() } java { toolchain { languageVersion.set(JavaLanguageVersion.of(20)) vendor.set(JvmVendorSpec.GRAAL_VM) } } application { mainClass.set("example.App") }
GraalVMを導入済みでない場合は、foojay-resolver-convention
で定義された https://github.com/graalvm/graalvm-ce-builds/releases
から graalvm-community-jdk-20.0.2_macos-x64_bin.tar.gz
をダウンロードして、自動的に ~/.gradle/jdks
に配備してくれる。
本来は、graalvm-community-openjdk-20.0.2+9.1/Contents/Home/bin/native-image
はシンボリックリンクで、lib/svm/bin/native-image
にリンクするが、実体は0バイトのファイルになりシンボリックリンクが壊れている。
そのため、native-image のコマンド呼び出しが何も行うことなく終了してネイティブイメージは生成できない。
これは、古くからある以下の Issue にある通り、Gradle がシンボリックリンクを理解しないため。
ワークアラウンドとしては、別途 GraalVM をインストールするか、~/.gradle/jdks
に残る graalvm-community-jdk-20.0.2_macos-x64_bin.tar.gz
をOS上で解凍して上書いてやれば良い。
Native Image Plugin(0.9.25)は、Gradle 8.3 では動かない
Gradle 8.3 では、ネイティブ・イメージ・プラグインは以下のエラーとなり動作しない。
The value for property 'languageVersion' is final and cannot be changed any further.
原因はこちらで、プラグイン側の修正待ちの状態。
ワークアラウンドとしては、GraalVM Native Image Plugin (<0.9.25) を使うには、Gradle 8.2 を使えば良い。
本事象は GraalVM Native Image Plugin 0.9.26 で改善されたようです
Native Image Plugin のトレースエージェントは GRAALVM_HOME / JAVA_HOME が必須
トレースエージェントで実行する場合は以下のタスクを実行する。
$ ./gradlew -Pagent run $ ./gradlew metadataCopy --task run --dir src/main/resources/META-INF/native-image
しかし、いずれも以下のエラーとなる。
Execution failed for task ':app:run'. > Cannot query the value of this property because it has no value available.
Native Image Plugin のタスクで以下のようになっており、環境変数が必須になってしまっている。
public class NativeImageExecutableLocator { public static Provider<String> graalvmHomeProvider(ProviderFactory providers, Diagnostics diagnostics) { return diagnostics.fromEnvVar("GRAALVM_HOME", providers) .orElse(diagnostics.fromEnvVar("JAVA_HOME", providers)); }
ツールチェーン指定しているにも関わらず、環境変数のエクスポートが必要。
$ export GRAALVM_HOME=~/.gradle/jdks/graalvm_community-20-x86_64-os_x/graalvm-community-openjdk-20.0.2+9.1/Contents/Home