Avatar ·

Ошибка сборки Android Studio: несовместимость target Java 1.8 и 17 в kapt

Всем привет! Я новичок в Android-разработке на Kotlin, и при сборке проекта в Android Studio у меня возникла ошибка, которую я никак не могу исправить. Вот что пишет Gradle: ``` Execution failed for task ':app:kaptGenerateStubsDebugKotlin'. > 'compileDebugJavaWithJavac' task (current target is 1.8) and 'kaptGenerateStubsDebugKotlin' task (current target is 17) have different JVM target compatibility. ``` Я использую Kotlin 1.9.0, Android Gradle Plugin 8.1.0, compileSdk 34, targetSdk 34. В моем `build.gradle.kts` (уровня модуля) я явно указал `compileOptions` с `sourceCompatibility = JavaVersion.VERSION_1_8` и `targetCompatibility = JavaVersion.VERSION_1_8`, потому что читал, что это нужно для совместимости со старыми библиотеками. Вот фрагмент кода: ```kotlin android { compileSdk = 34 defaultConfig { applicationId = "com.example.myapp" minSdk = 24 targetSdk = 34 versionCode = 1 versionName = "1.0" } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } } ``` Я также пробовал менять `jvmTarget` на "17" в `kotlinOptions`, но тогда появляются другие ошибки про несовместимость с библиотеками. Как правильно настроить проект, чтобы убрать эту ошибку? Что вообще означает это сообщение? Заранее спасибо за помощь! <<>>

Причина ошибки

Ошибка возникает из-за несоответствия JVM-таргетов между задачей компиляции Java (compileDebugJavaWithJavac) и задачей генерации заглушек для kapt (kaptGenerateStubsDebugKotlin). Начиная с Kotlin 1.9.0 и Android Gradle Plugin 8.x, процесс сборки стал строже: если вы явно устанавливаете jvmTarget = "1.8" в kotlinOptions, то kapt ожидает, что и Java-часть будет компилироваться с тем же таргетом, но AGP 8.x по умолчанию использует Java 17 для внутренних задач. В результате возникает конфликт: Java-компилятор работает с target 1.8, а kapt-задача — с target 17.

Решение: синхронизируйте JVM-таргеты

Самый правильный и современный способ — поднять JVM-таргет до 17 (или хотя бы до 11), так как Android Gradle Plugin 8.x и Kotlin 1.9+ требуют более новую JVM для работы. Если ваш minSdk >= 24 (как в вашем случае), то Java 8 не нужен — Android Studio прекрасно поддерживает Java 11 и 17 для компиляции, а на устройстве это не влияет, потому что байткод преобразуется в DEX.

Измените ваш build.gradle.kts уровня модуля следующим образом:

android {
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }

    kotlinOptions {
        jvmTarget = "17"
    }
}

После этого сделайте File → Invalidate Caches and Restart и затем Build → Clean Project, чтобы сбросить кэши. Ошибка должна исчезнуть.

Альтернатива: если вы не можете поднять таргет

Если по каким-то причинам (например, жёсткие требования legacy-библиотек) вы вынуждены использовать Java 1.8, то можно явно указать kapt использовать тот же таргет через kapt.use.jvm.target в gradle.properties:

# gradle.properties
kapt.use.jvm.target=1.8

Но это не рекомендуется, так как может привести к другим проблемам совместимости с новыми версиями плагинов и Kotlin.

Почему это произошло?

Начиная с AGP 8.0, плагин по умолчанию использует Java 17 для своих внутренних задач (например, для компиляции Java-кода, генерируемого kapt). Kotlin 1.9.0 также по умолчанию компилируется с target 17, если не указано иное. Когда вы вручную понижаете target до 1.8, вы создаёте несоответствие между двумя этапами сборки.

  • compileDebugJavaWithJavac — компилирует Java-код вашего проекта (включая сгенерированный код) с указанным target.
  • kaptGenerateStubsDebugKotlin — генерирует заглушки для kapt (Java-стабы из Kotlin-кода), которые потом компилируются Java-компилятором. Если таргеты разные — ошибка.

После исправления всё будет работать штатно, и вы сможете использовать все возможности Kotlin 1.9+.

<<>>

Дополнительный подход: полное удаление kapt и переход на KSP

Если вы используете kapt только для библиотек вроде Dagger, Room или Glide, рассмотрите возможность миграции на KSP (Kotlin Symbol Processing). KSP — это более быстрая и современная альтернатива kapt, которая не требует генерации Java-заглушек и, соответственно, не страдает от проблем с JVM-таргетами.

Для этого в build.gradle.kts уровня проекта добавьте плагин KSP:

plugins {
    id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false
}

В модульном файле подключите его и замените kapt на ksp:

plugins {
    id("com.android.application")
    kotlin("android")
    id("com.google.devtools.ksp")
}

dependencies {
    // Вместо kapt("androidx.room:room-compiler:2.6.1")
    ksp("androidx.room:room-compiler:2.6.1")
}

После этого ошибка с JVM-таргетами исчезнет навсегда, а сборка будет быстрее. Однако убедитесь, что все используемые библиотеки поддерживают KSP (большинство современных уже поддерживают).