KotlinプロジェクトでGradle 7.6.2 -> Gradle 8.3移行をした時の作業メモ

自分が取り組んでいるKotlinOSSプロジェクトにて、Gradle 7.6.2 -> Gradle 8.3の移行をやった際にハマったことのメモです。

github.com

きっかけ

このプロジェクトには、GitHub ActionsKotlin x Javaのバージョンを組み合わせ毎の挙動を確認するグリッドテストが有ります。

このテストにK2コンパイラを使うパターンも追加しようとした所、関係の無いはずのケースが失敗するようになりました。
エラーログを確認した所キャッシュ起因に見えたので、キャッシュを全消ししてやり直した所、当該箇所は直ったものの、今度はJava 20を使うケース全てが失敗するようになりました。

エラーログには以下のように表示されていました。

* What went wrong:
Could not open cp_init generic class cache for initialization script '/home/runner/.gradle/init.d/gradle-build-action.build-result-capture.init.gradle' (/home/runner/.gradle/caches/7.6.2/scripts/9b672n24db1z169ivld6c2v82).
> BUG! exception in phase 'semantic analysis' in source unit '_BuildScript_' Unsupported class file major version 64

対応

Gradleのアップデート

エラーログを検索したところ、Javaバージョンの不整合という情報が引っかかったため、Gradleバージョンの移行を決断しました。

discuss.gradle.org

バージョンアップは以下の2コマンドを実行することで行いました。

./gradlew wrapper --gradle-version=8.3
./gradlew wrapper

build.gradle.ktsの修正

buildDir -> layout.buildDirectory

プロジェクト内でbuildDirを参照している部分が有りましたが、当該プロパティは非推奨化していたので、以下のように変更を行いました。

- val generatedSrcPath = "$buildDir/generated/kotlin"
+ val generatedSrcPath = "${layout.buildDirectory.get()}/generated/kotlin"

compileTestKotlinへのjvmTarget指定

変更後、Kotlin 1.8以降 & Java 11以上の場合compileTestKotlinが落ちるようになりました。
エラーログは以下のようになっておりました。

* What went wrong:
Execution failed for task ':compileTestKotlin'.
> 'compileTestJava' task (current target is 1.8) and 'compileTestKotlin' task (current target is 11) jvm target compatibility should be set to the same Java version.
  Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain

当該プロジェクトではjvmTargetJava 8を指定していますが、どうもKotlin 1.8以降の場合compileTestKotlin側にも同様の指定が無ければ不整合扱いになるようです。
以下の記述を追記して対応しました(もしかするとjvmTargetを消す方が望ましいかもしれません)。

tasks {
    /* 略 */
+   compileTestKotlin {
+       kotlinOptions.jvmTarget = "1.8"
+   }
    /* 略 */
}

感想

最初のバグは何だったのか、何故キャッシュ削除前はJava 20のテストが成功していたのか、深い謎が残りましたが、一旦K2のテストも成功しているので気にしないことにします……。