며칠 전 안드로이드 컨퍼런스에서 지인분께 드린 카카오뱅크 과제 Repository가 빌드가 되지 않는다는 제보를 받았습니다.
제가 사용하는 환경에서는 정상적으로 빌드되는 것을 확인하여, Canary build인 Giraffe 버전을 사용하여 AGP 버전을 8.1.0-alpha9 이상 빌드 시 아래와 같은 오류가 발생함을 확인하였습니다.
Caused by: org.gradle.api.GradleException: 'compileDebugJavaWithJavac' task (current target is 1.8) and 'kaptGenerateStubsDebugKotlin' task (current target is 17) jvm target compatibility should be set to the same Java version.
❓ 발생 원인
Java toolchains(자바 툴체인)은 Java 프로젝트를 build 하고 실행하기 위한 도구 세트로,
기본적으로 Gradle은 JVM 프로젝트를 빌드하는 데 동일한 Java toolchains를 사용하지만,
개발 환경에 따른 Java 버전의 차이가 있거나 빌드가 불가능할 수 있습니다.
따라서 Gradle에서는 프로젝트 또는 Tasks 수준에서 Java 버전을 선택할 수 있도록 툴체인을 설정할 수 있습니다.
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
// vendor.set(JvmVendorSpec.ADOPTIUM)
// implementation.set(JvmImplementation.J9)
}
}
Kotlin은 1.5.30버전 부터 Java toolchains를 공식적으로 지원하였습니다.
그래서 kotlin scope내에 아래와 같은 형식으로 작성할 수도 있습니다.
// Before Kotlin 1.7.20
kotlin {
jvmToolchain {
val javaVersion = JavaVersion.VERSION_17.toString()
languageVersion.set(JavaLanguageVersion.of(javaVersion))
}
}
// or alternatively
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
// After Kotlin 1.7.20
kotlin {
jvmToolchain(17)
}
Android의 경우 AGP(Android Gradle Plugins) 플러그인에서 위의 방식으로 선언된 jvmToolchain값을 사용하여 Kotlin의 JDK 대상을 선언하고 Java로 컴파일이 지원돼야 합니다.
위처럼 kotlin scope를 추가하지 않고 android내에 선언할 수도 있습니다.
// if Android
kotlin {
jvmToolchain(17)
}
android {
...
kotlinOptions {
// Don't need to add jvmTarget
}
...
}
그러나 버그로 인해 AGP 8.1.0-alpha09까지 올바른 버전이 반영되고 있지 않습니다.
이와 관련하여 Configure a Gradle project | Kotlin Documentation (kotlinlang.org)에서 경고하고 있으며,
Setting JVM toolchain does not affect JavaCompile targetCompatibility value [260059413]- Issue Tracker (google.com)에서 버그 사항으로 추적되고 있습니다.
❗ 해결 방법
아래처럼 모든 모듈의 build.gradle.kts의 android 블록 내에 jvmTarget 및 sourceCompatibility, targetCompatibility 선언을 해야합니다.
kotlin {
jvmToolchain(17)
}
android {
...
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
...
}
jvmTarget은 선언하지 않을 경우 기본 타겟인 11로 선언됩니다. (구 버전에서는 8로 선언됩니다.)
멀티 모듈 사용 시 build-logic 모듈을 만들어 플러그인 형식으로 통합 관리 하는 것을 추천합니다.
수정한 Issue 사항은 이곳에서 확인할 수 있습니다.
https://github.com/daryeou/kakao-assignment
ⓒ 굿햄 2022. daryeou@gmail.com all rights reserved.
댓글