Avatar ·

Ошибка "Kotlin runtime JAR files in the classpath should have the same version": что делать?

Привет! Я новичок в Kotlin и пытаюсь собрать свой первый проект с использованием Gradle. У меня есть простой файл `Main.kt`: ```kotlin fun main() { println("Hello, Kotlin!") } ``` Я подключил плагин Kotlin в `build.gradle.kts`: ```kotlin plugins { kotlin("jvm") version "1.8.0" } ``` Но когда я запускаю сборку через `./gradlew build`, я получаю такое предупреждение: ``` warning: Kotlin runtime JAR files in the classpath should have the same version (found 1.8.0, 1.7.10 in classpath) ``` Я проверил свои зависимости — у меня нет ничего стороннего, только стандартная библиотека Kotlin. Почему возникает это предупреждение? Я использую IntelliJ IDEA, если это важно. Пожалуйста, объясните, что это значит и как это исправить. Заранее спасибо! <<>>

Причина предупреждения

Это предупреждение возникает, когда в classpath вашего проекта оказываются JAR-файлы Kotlin runtime разных версий. В вашем случае — версия 1.8.0 (указанная в плагине) и 1.7.10 (вероятно, откуда-то ещё). Kotlin требует, чтобы все runtime-компоненты (kotlin-stdlib, kotlin-reflect, kotlin-script-runtime и т.д.) были одной версии, иначе возможны ошибки компиляции или выполнения.

Основные причины

  • Транзитивные зависимости: Какая-то библиотека, которую вы подключили, сама тянет старую версию Kotlin stdlib.
  • Конфликт версий в многомодульном проекте: Разные модули используют разные версии Kotlin plugin.
  • IDE подсовывает старый JAR: IntelliJ IDEA может кешировать старые версии Kotlin runtime.

Решение

Самый надёжный способ — явно указать версию Kotlin stdlib в блоке dependencies и зафиксировать её с помощью constraints или strictly в Gradle.

// build.gradle.kts
plugins {
    kotlin("jvm") version "1.8.0"
}

dependencies {
    implementation(kotlin("stdlib"))
    // Если используете reflection
    implementation(kotlin("reflect"))
    // Явно указываем версию для всех транзитивных зависимостей
    constraints {
        implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.0") {
            because("Требуется единая версия Kotlin runtime")
        }
        implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.0") {
            because("Предотвращение конфликта версий")
        }
    }
}

Проверка зависимостей

Выполните команду, чтобы увидеть, откуда берётся старая версия:

./gradlew dependencies --configuration runtimeClasspath | grep kotlin

В выводе вы увидите цепочку зависимостей. Например:

org.jetbrains.kotlin:kotlin-stdlib:1.8.0
\--- com.example:some-library:2.0.0
     \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 (forced)

Если библиотека some-library тянет старую версию, вы можете:

  • Обновить эту библиотеку до последней версии (возможно, она уже поддерживает Kotlin 1.8).
  • Принудительно исключить старую зависимость:
implementation("com.example:some-library:2.0.0") {
    exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
}

Если проблема в IntelliJ IDEA

Иногда IDE кеширует старые JAR-файлы Kotlin. Сделайте:

  1. File → Invalidate Caches and Restart.
  2. После перезапуска выполните Build → Rebuild Project.
  3. Убедитесь, что в File → Project Structure → SDK указана правильная версия Kotlin (1.8.0).

Автоматическое решение с помощью Kotlin BOM

Начиная с Kotlin 1.8.0, можно использовать Bill of Materials (BOM) для автоматического выравнивания версий:

dependencies {
    implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
    implementation("org.jetbrains.kotlin:kotlin-stdlib")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
}

BOM гарантирует, что все артефакты Kotlin будут одной версии.

После любого из этих решений пересоберите проект. Предупреждение должно исчезнуть.

<<>>

Альтернативный подход: использование Gradle Versions Plugin

Если у вас большой проект с множеством зависимостей, ручное исключение каждой конфликтующей библиотеки может быть утомительным. Вместо этого можно воспользоваться плагином Gradle Versions Plugin или встроенным механизмом resolution strategy.

// build.gradle.kts
configurations.all {
    resolutionStrategy {
        // Принудительно использовать единую версию Kotlin
        force("org.jetbrains.kotlin:kotlin-stdlib:1.8.0")
        force("org.jetbrains.kotlin:kotlin-reflect:1.8.0")
        force("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0")
    }
}

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

Рекомендую сначала проверить, совместима ли библиотека с Kotlin 1.8.0, используя её документацию или issue tracker. Если нет — обновите саму библиотеку до версии, поддерживающей Kotlin 1.8.