自分が取り組んでいるKotlin製OSSプロジェクトにて、Gradle 7.6.2 -> Gradle 8.3の移行をやった際にハマったことのメモです。
きっかけ
このプロジェクトには、GitHub ActionsでKotlin 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バージョンの移行を決断しました。
バージョンアップは以下の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
当該プロジェクトではjvmTargetにJava 8を指定していますが、どうもKotlin 1.8以降の場合compileTestKotlin側にも同様の指定が無ければ不整合扱いになるようです。
以下の記述を追記して対応しました(もしかするとjvmTargetを消す方が望ましいかもしれません)。
tasks {
/* 略 */
+ compileTestKotlin {
+ kotlinOptions.jvmTarget = "1.8"
+ }
/* 略 */
}
感想
最初のバグは何だったのか、何故キャッシュ削除前はJava 20のテストが成功していたのか、深い謎が残りましたが、一旦K2のテストも成功しているので気にしないことにします……。