
- はじめに
- 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