Android アプリのプロジェクトで Gradle 8.0 移行に更新すると(ここでは not Android Gradle Plugin) kapt や ksp を使っているプロジェクトによっては以下のようなエラーが出ることがあります。
Execution failed for task ':app:kaptGenerateStubsDebugKotlin'.
> 'compileDebugJavaWithJavac' task (current target is 11) and 'kaptGenerateStubsDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain
この場合はエラーに書かれている Java Toolchain に置き換えるよりも以下のコードで Kotlin のコンパイルタスクが実行される JVM のバージョンを固定する方が現時点では対処しやすいかもしれない。
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>()
.configureEach {
kotlinOptions {
// targetCompatibilityと揃える
jvmTarget = JavaVersion.VERSION_XXX.toString()
}
}
起きている問題の解説
これは Java と Kotlin のコンパイル時に target JVM のバージョンが一致していない場合に出るエラーで、Gradle 8.0 の更新で以下のような状況から JVM のずれが生じます。
- Gradle 8.0 から Gradle の Kotlin DSL が 1.8 になった
- Kotlin DSL 1.8 ではビルドを実行する JDK のバージョンを使用する
- Android Studio Flamingo についている JDK は 17
- Android のプロジェクトの target JVM は 17 でない(大抵 8 or 11)
以下の記事でもこの辺りの変更点が解説されていてとても参考になる。
問題の回避策と罠
エラーに書かれているように Java Toolchain で実行される JVM のバージョンを揃えるのが本当は望ましい。
将来的にも Java Toolchain で統一されそうで移行されていくことになるはず。
しかし、Java Toolchain で揃えようとするといくつか罠がある。
1. Android Studio Flamingo 以降の JDK は 17 がバンドルされている
このため、Java Toolchain で JVM のバージョンを 11 に設定しようとした場合は、プロジェクトで使用される JDK も 11 にダウングレードするもしくは Java Toolchain での自動ダウンロードの設定をすることになる。
Package Manager が入っていればそこからなければ別途設定が必要であったり、CI/CD でも必要とする JDK のバージョンがない場合に何かしらの手段で JDK を使える状態にする必要がある。
2. Desugar は JVM 17 に対応していない
1 の回避として Toolchain で JVM とプロジェクトを 17 に設定しようという案も出るとは思うが、Desugar は JVM 17 に対応していないのでプロジェクト全体を 17 にすることは避けた方がいいらしい(ドキュメントには Java 11+ とあるけど…)。
3. Android Gradle Plugin における Java Toolchain のサポートは AGP 8.1.0-alpha09 以降
compileOptions の targetCompatibility も将来的には Java Toolchain に統一されるがそれは AGP 8.1.0-alpha09 以降となる。
ここで 2 の問題があるのでどのみち Java Toolchain で統一する場合は Desugar が対応されるまで 11 にするしかなく、1 の調整が必要となる。
Java Toolchain に移行するにはプロジェクトの環境によってすんなり移行できないことがあるため、しばらくは kotlinOptions.jvmTarget
で様子を見る方がいいかもしれないというお話。