Android 빌드의 Java 버전

소스 코드가 자바로 작성되었는지 Kotlin으로 작성되었는지 또는 둘 다로 작성되었는지와 관계없이 빌드에 대해 JDK 또는 자바 언어 버전을 선택해야 하는 곳이 많이 있습니다.

Gradle 빌드의 JDK 관계 개요

용어집

JDK (Java Development Kit)
Java 개발 키트 (JDK)에는 다음이 포함됩니다.
  • 컴파일러, 프로파일러, 보관 파일 생성자와 같은 도구 이는 빌드 중 애플리케이션을 만들기 위해 백그라운드에서 사용됩니다.
  • Kotlin 또는 Java 소스 코드에서 호출할 수 있는 API가 포함된 라이브러리입니다. 일부 함수는 Android에서 사용할 수 없습니다.
  • 자바 애플리케이션을 실행하는 인터프리터인 자바 가상 머신 (JVM) JVM을 사용하여 Android 스튜디오 IDE 및 Gradle 빌드 도구를 실행합니다. JVM은 Android 기기나 에뮬레이터에서 사용되지 않습니다.
JetBrains Runtime (JBR)
JetBrains Runtime (JBR) 은 Android 스튜디오와 함께 배포되는 향상된 JDK입니다. 여기에는 스튜디오 및 관련 JetBrains 제품에서 사용하기 위한 몇 가지 최적화가 포함되어 있지만 다른 자바 애플리케이션을 실행하는 데도 사용할 수 있습니다.

Android 스튜디오를 실행하기 위해 JDK를 선택하려면 어떻게 해야 하나요?

JBR을 사용하여 Android 스튜디오를 실행하는 것이 좋습니다. 이 도구는 Android 스튜디오와 함께 배포되고 Android 스튜디오를 테스트하는 데 사용되며, 최적의 Android 스튜디오 사용을 위한 개선사항을 포함하고 있습니다. 이를 위해 STUDIO_JDK 환경 변수를 설정하지 마세요.

Android 스튜디오의 시작 스크립트는 다음 순서로 JVM을 찾습니다.

  1. STUDIO_JDK 환경 변수
  2. studio.jdk 디렉터리 (Android 스튜디오 배포 내)
  3. Android 스튜디오 배포판의 jbr 디렉터리 (JetBrains 런타임)입니다. 추천
  4. JDK_HOME 환경 변수
  5. JAVA_HOME 환경 변수
  6. PATH 환경 변수의 java 실행 파일

Gradle 빌드를 실행할 JDK를 어떻게 선택하나요?

Android 스튜디오의 버튼을 사용하여 Gradle을 실행하면 Android 스튜디오 설정에 설정된 JDK를 사용하여 Gradle을 실행합니다. Android 스튜디오 내부 또는 외부의 터미널에서 Gradle을 실행하는 경우 JAVA_HOME 환경 변수(설정된 경우)에 따라 Gradle 스크립트를 실행하는 JDK가 결정됩니다. JAVA_HOME가 설정되어 있지 않으면 PATH 환경 변수에서 java 명령어를 사용합니다.

가장 일관된 결과를 얻으려면 JAVA_HOME 환경 변수와 Android 스튜디오의 Gradle JDK 구성을 동일한 JDK로 설정해야 합니다.

빌드를 실행할 때 Gradle은 실제 빌드를 실행하기 위해 daemon이라는 프로세스를 만듭니다. 빌드가 동일한 JDK 및 Gradle 버전을 사용하는 한 이 프로세스를 재사용할 수 있습니다. 데몬을 재사용하면 새 JVM을 시작하고 빌드 시스템을 초기화하는 시간이 줄어듭니다.

다른 JDK 또는 Gradle 버전으로 빌드를 시작하면 추가 데몬이 생성되어 CPU와 메모리를 더 많이 사용합니다.

Android 스튜디오의 Gradle JDK 구성

기존 프로젝트의 Gradle JDK 구성을 수정하려면 File (macOS의 경우 Android 스튜디오) > Settings > Build, Execution, Deployment > Build Tools > Gradle에서 Gradle 설정을 엽니다. Gradle JDK 드롭다운에는 선택할 수 있는 다음 옵션이 포함되어 있습니다.

  • 매크로(예: JAVA_HOME, GRADLE_LOCAL_JAVA_HOME)
  • Android 구성 파일에 저장된 vendor-version 형식의 JDK 테이블 항목(예: jbr-17)
  • JDK 다운로드
  • 특정 JDK 추가
  • 운영체제의 기본 JDK 설치 디렉터리에서 로컬로 감지된 JDK

선택한 옵션은 프로젝트 .idea/gradle.xml 파일의 gradleJvm 옵션에 저장되고, Android 스튜디오를 통해 시작할 때 Gradle을 실행하는 데 JDK 경로 변환이 사용됩니다.

그림 1. Android 스튜디오의 Gradle JDK 설정

매크로는 동적 프로젝트 JDK 경로 선택을 사용 설정합니다.

  • JAVA_HOME: 이름이 같은 환경 변수를 사용합니다.
  • GRADLE_LOCAL_JAVA_HOME: .gradle/config.properties 파일에서 java.home 속성을 사용하며 기본값은 JetBrains 런타임입니다.

선택된 JDK는 빌드 스크립트 및 소스 코드를 수정할 때 Gradle 빌드를 실행하고 JDK API 참조를 확인하는 데 사용됩니다. 지정된 compileSdk는 소스 코드를 수정하고 빌드할 때 사용할 수 있는 Java 기호를 추가로 제한합니다.

Gradle 빌드에서 사용하는 플러그인에 사용되는 JDK 버전보다 높거나 같은 JDK 버전을 선택해야 합니다. Android Gradle 플러그인 (AGP)에 필요한 최소 JDK 버전을 확인하려면 출시 노트의 호환성 표를 참고하세요.

예를 들어 Android Gradle 플러그인 버전 8.x에는 JDK 17이 필요합니다. 이전 버전의 JDK와 함께 사용하는 Gradle 빌드를 실행하려고 하면 다음과 같은 메시지가 보고됩니다.

An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 17 to run. You are currently using Java 11.
      Your current JDK is located in /usr/local/buildtools/java/jdk11
      You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.

Java 또는 Kotlin 소스 코드에서 사용할 수 있는 Java API는 무엇인가요?

Android 애플리케이션은 JDK에 정의된 일부 API를 사용할 수 있지만 모든 API를 사용할 수는 없습니다. Android SDK는 여러 Java 라이브러리 함수의 구현을 사용 가능한 API의 일부로 정의합니다. compileSdk 속성은 Kotlin 또는 Java 소스 코드를 컴파일할 때 사용할 Android SDK 버전을 지정합니다.

Kotlin

android {
    ...
    compileSdk = 33
}

Groovy

android {
    ...
    compileSdk 33
}

각 Android 버전은 특정 버전의 JDK와 사용 가능한 Java API의 하위 집합을 지원합니다. 지정된 minSdk에서 사용할 수 없는 compileSdk에서 사용할 수 있는 Java API를 사용하는 경우 디슈가링이라고 하는 프로세스를 통해 이전 버전의 Android에서 API를 사용할 수 있습니다. 지원되는 API는 디슈가링을 통해 사용할 수 있는 자바 11+ API를 참고하세요.

이 표를 사용하여 각 Android API에서 지원하는 Java 버전과 사용 가능한 Java API의 세부정보를 찾을 수 있습니다.

Android Java 지원되는 API 및 언어 기능
14 (API 34) 17 핵심 라이브러리
13 (API 33) 11 핵심 라이브러리
12 (API 32) 11 Java API
11 이하 Android 버전

어떤 JDK에서 Java 소스 코드를 컴파일하나요?

자바 도구 모음 JDK에는 모든 자바 소스 코드를 빌드하는 데 사용되는 자바 컴파일러가 포함되어 있습니다. 이 JDK는 빌드 중에 실행되는 Kotlin 컴파일러 (JVM에서 실행), javadoc, 테스트도 실행합니다.

도구 모음의 기본값은 Gradle을 실행하는 데 사용되는 JDK입니다. 기본값을 사용하고 다른 머신 (예: 로컬 머신과 별도의 지속적 통합 서버)에서 빌드를 실행하는 경우 다른 JDK 버전을 사용하면 빌드 결과가 다를 수 있습니다.

일관성이 더 높은 빌드를 만들려면 자바 도구 모음 버전을 명시적으로 지정하면 됩니다. 이를 지정하면 다음과 같이 됩니다.

  • 빌드를 실행 중인 시스템에서 호환되는 JDK를 찾습니다.
    • 호환되는 JDK가 없고 도구 모음 리졸버가 정의된 경우 JDK를 다운로드합니다.
  • 소스 코드에서 호출을 위해 도구 모음 Java API를 노출합니다.
  • Java 언어 버전을 사용하여 Java 소스를 컴파일합니다.
  • sourceCompatibilitytargetCompatibility의 기본값을 제공합니다.

항상 Java 도구 모음을 지정하고 지정된 JDK가 설치되어 있는지 확인하거나 도구 모음 리졸버를 빌드에 추가하는 것이 좋습니다.

소스 코드가 자바, Kotlin 또는 둘 다로 작성되었는지에 관계없이 도구 모음을 지정할 수 있습니다. 모듈의 build.gradle(.kts) 파일 최상위 수준에서 도구 모음을 지정합니다.

소스 코드가 자바로만 작성된 경우 다음과 같이 자바 도구 모음 버전을 지정합니다.

Kotlin

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

Groovy

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

소스가 Kotlin으로만 구성되거나 Kotlin과 자바의 혼합인 경우 자바 도구 모음 버전을 다음과 같이 지정합니다.

Kotlin

kotlin {
    jvmToolchain(17)
}

Groovy

kotlin {
    jvmToolchain 17
}

도구 모음 JDK 버전은 Gradle을 실행하는 데 사용되는 JDK와 동일할 수 있지만 다른 용도로 사용된다는 점에 유의하세요.

Java 소스 코드에서 사용할 수 있는 Java 언어 소스 기능은 무엇인가요?

sourceCompatibility 속성은 자바 소스를 컴파일하는 동안 사용할 수 있는 자바 언어 기능을 결정합니다. Kotlin 소스에는 영향을 미치지 않습니다.

지정하지 않으면 Gradle을 실행하는 데 사용되는 자바 도구 모음 또는 JDK가 기본값입니다. 항상 도구 모음 (선호됨) 또는 sourceCompatibility를 명시적으로 지정하는 것이 좋습니다.

모듈의 build.gradle(.kts) 파일에 sourceCompatibility를 지정합니다.

Kotlin

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
    }
}

Groovy

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
    }
}

Kotlin 또는 Java 소스를 컴파일할 때 어떤 Java 바이너리 기능을 사용할 수 있나요?

targetCompatibilityjvmTarget를 지정하면 컴파일된 자바와 Kotlin 소스의 바이트 코드를 생성할 때 사용되는 자바 클래스 형식 버전이 결정됩니다.

일부 Kotlin 기능은 상응하는 Java 기능이 추가되기 전에 있었습니다. 초기 Kotlin 컴파일러는 이러한 Kotlin 기능을 나타내는 자체 방식을 만들어야 했습니다. 이러한 기능 중 일부는 나중에 Java에 추가되었습니다. 이후 jvmTarget 수준에서는 Kotlin 컴파일러가 자바 기능을 직접 사용할 수 있으므로 성능이 향상될 수 있습니다.

targetCompatibility의 기본값은 sourceCompatibility와 동일한 값이지만 지정된 경우 sourceCompatibility 이상이어야 합니다.

jvmTarget의 기본값은 도구 모음 버전입니다.

Android 버전에 따라 지원하는 자바 버전이 다릅니다. targetCompatibilityjvmTarget를 늘려 추가 자바 기능을 활용할 수 있지만 이 경우 기능을 사용할 수 있도록 최소 Android SDK 버전도 늘려야 할 수 있습니다.

Kotlin

android {
    compileOptions {
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

Groovy

android {
    compileOptions {
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget '17'
    }
}