본문 바로가기
Android/Error Report

[Gradle] Kotlin Java toolchains(툴체인) 관련 오류 해결 방법, with AGP 8.1

by 굿햄 2023. 4. 6.

며칠 전 안드로이드 컨퍼런스에서 지인분께 드린 카카오뱅크 과제 Repository가 빌드가 되지 않는다는 제보를 받았습니다.

AGP 8.1.0-alpha8에서 툴체인만 선언 시

제가 사용하는 환경에서는 정상적으로 빌드되는 것을 확인하여, 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
    }
    ...
}

 

AGP 8.1.0-alpha8에서 compileOptions 선언 시

jvmTarget은 선언하지 않을 경우 기본 타겟인 11로 선언됩니다. (구 버전에서는 8로 선언됩니다.)

 

멀티 모듈 사용 시 build-logic 모듈을 만들어 플러그인 형식으로 통합 관리 하는 것을 추천합니다.

 

수정한 Issue 사항은 이곳에서 확인할 수 있습니다.

https://github.com/daryeou/kakao-assignment

 

GitHub - daryeou/kakao-assignment: 2023 카카오뱅크 안드로이드 사전과제

2023 카카오뱅크 안드로이드 사전과제. Contribute to daryeou/kakao-assignment development by creating an account on GitHub.

github.com


ⓒ 굿햄 2022. daryeou@gmail.com all rights reserved.

 

댓글