Avatar ·

Дублирование класса Kotlin: как исправить ошибку "Duplicate class" в Android

Всем привет! Я новичок в Kotlin и Android-разработке, и столкнулся с ошибкой, которую никак не могу победить. При сборке проекта вылетает: Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-1.8.0 (org.jetbrains.kotlin:kotlin-stdlib:1.8.0) and kotlin-stdlib-jdk8-1.7.0 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0) Я использую Android Studio, проект на Kotlin. В build.gradle (app) у меня подключены зависимости: dependencies { implementation 'androidx.core:core-ktx:1.9.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.8.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.google.code.gson:gson:2.10.1' } Я читал, что это из-за конфликта версий Kotlin, но не понимаю, как это исправить. Удаление одной из зависимостей приводит к другим ошибкам. Подскажите, что делать? Может, нужно обновить Gradle или плагин Kotlin? Заранее спасибо! <<>>

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

Ошибка Duplicate class возникает, когда в проекте оказывается несколько одинаковых классов из разных библиотек или версий одной библиотеки. В вашем случае — конфликт между kotlin-stdlib:1.8.0 и kotlin-stdlib-jdk8:1.7.0. Начиная с Kotlin 1.8.0, функциональность kotlin-stdlib-jdk8 была включена непосредственно в kotlin-stdlib, поэтому их одновременное использование приводит к дублированию.

Решение: удалить лишнюю зависимость

Самый простой и правильный способ — удалить kotlin-stdlib-jdk8 из build.gradle. В современных проектах Kotlin (1.8+) достаточно только kotlin-stdlib. Если вы используете плагин Kotlin, то kotlin-stdlib добавляется автоматически — явная версия не нужна.

dependencies {
    implementation 'androidx.core:core-ktx:1.9.0'
    // Удалите строку ниже
    // implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.0'
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.google.code.gson:gson:2.10.1'
}

Проверка через Gradle-задачи

Если после удаления ошибка осталась, возможно, другая библиотека транзитивно тянет старую версию. Выполните в терминале:

./gradlew :app:dependencies --configuration implementation

Найдите в выводе kotlin-stdlib-jdk8. Затем исключите его из конкретной зависимости:

implementation ('com.squareup.retrofit2:retrofit:2.9.0') {
    exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}

Глобальное исключение через constraints

Более мощный способ — использовать constraints в блоке dependencies:

dependencies {
    constraints {
        implementation('org.jetbrains.kotlin:kotlin-stdlib-jdk8') {
            because 'Функциональность jdk8 включена в kotlin-stdlib начиная с 1.8'
        }
    }
    // остальные зависимости
}

Обновление плагина Kotlin

Убедитесь, что версия плагина Kotlin в корневом build.gradle совпадает с версией kotlin-stdlib:

plugins {
    id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
}

В build.gradle (app):

plugins {
    id 'org.jetbrains.kotlin.android'
}
// Уберите явную implementation 'kotlin-stdlib', плагин добавит её сам

Очистка кэша

После изменений выполните:

Build -> Clean Project
File -> Invalidate Caches... -> Invalidate and Restart

Альтернатива: миграция на Kotlin 2.0+

Если проект позволяет, обновитесь до Kotlin 2.0.0 или выше. В этой версии kotlin-stdlib-jdk8 полностью удалён, и конфликт невозможен.

Итог

  • Удалите kotlin-stdlib-jdk8 из явных зависимостей.
  • Используйте единую версию kotlin-stdlib (или полагайтесь на плагин).
  • Исключайте транзитивные зависимости при необходимости.
  • Держите плагин Kotlin и библиотеки в актуальном состоянии.

После этих шагов ошибка Duplicate class исчезнет, и сборка пройдёт успешно.

<<>>

Использование Gradle Resolution Strategy

Если вы не хотите удалять зависимость вручную, можно принудительно указать Gradle, какую версию библиотеки использовать. Добавьте в корневой build.gradle (project-level) блок:

subprojects {
    configurations.all {
        resolutionStrategy {
            force 'org.jetbrains.kotlin:kotlin-stdlib:1.8.0'
            force 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0' // если нужна
        }
    }
}

Это заставит Gradle использовать только указанные версии для всех модулей. Недостаток — если другая библиотека требует старую версию, может возникнуть ошибка совместимости. Поэтому лучше использовать первый метод (удаление лишней зависимости).

Проверка через Gradle Scan

Для глубокой диагностики включите --scan при сборке:

./gradlew assembleDebug --scan

Откроется веб-отчёт, где будет видно, откуда берётся каждая зависимость. Это помогает найти скрытые конфликты.

Резюме

Метод с resolutionStrategy — быстрый костыль, но в долгосрочной перспективе лучше чистить зависимости и обновлять плагины.