Почему Kotlin JDK8 также включает Kotlin JDK7 в classpath?

#java #gradle #kotlin

#java #gradle #kotlin

Вопрос:

Я использую Kotlin для создания веб-сервиса и я наткнулся на то, что я считаю странным любопытством. С помощью этого build.gradle:

 group 'com.example'
version '0.1.0'

buildscript {
    ext.kotlinVersion = '1.2.71'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
    }
}

apply plugin: 'kotlin'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
    compile 'com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8'
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
  

Я получаю эту ошибку во время компиляции:

 w: Runtime JAR files in the classpath should have the same version. These files were found in the classpath:
    .../kotlin-stdlib-jdk8-1.2.71.jar (version 1.2)
    .../kotlin-stdlib-jdk7-1.2.71.jar (version 1.2)
    .../kotlin-reflect-1.3.10.jar (version 1.3)
    .../kotlin-stdlib-1.3.10.jar (version 1.3)
    .../kotlin-stdlib-common-1.3.10.jar (version 1.3)
  

ОК, нет проблем, jackson-module-kotlin подключается к зависимостям kotlin 1.3. Я могу их исключить. Но то, что привлекло мое внимание, была вторая строка. kotlin-stdlib-jdk8 также подключается kotlin-stdlib-jdk7 . На самом деле, я могу исключить это, и все по-прежнему будет работать как ожидалось:

 compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion") {
    exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib-jdk7"
}
  

Почему kotlin-stdlib-jdk8 в мой classpath добавляется, казалось бы, ненужное kotlin-stdlib-jdk7 ?

Комментарии:

1. Я полагаю, что они просто включили специфичный для java 8 материал в зависимость jdk8, оставив весь материал java 7 в jdk7. Итак, вам обоим нужно иметь полный стандартный файл. Я полагаю, вы также получаете общий stdlib, не так ли?

Ответ №1:

Предупреждение, которое вы видите во время компиляции, происходит потому, что jackson-module-kotlin:2.9.8 зависимость, по-видимому, приводит kotlin-stdlib:1.3.10 к пути к классу, и эта версия переопределяет вашу объявленную зависимость от 1.2.71. Чтобы избежать предупреждений, вам следует либо перенести свой проект на Kotlin 1.3.x, либо понизить jackson-module-kotlin зависимость до какой-либо предыдущей версии, которая зависит от Kotlin 1.2.x .

kotlin-stdlib-jdk8 является дополнением поверх kotlin-stdlib-jdk7 , а последнее является дополнением поверх kotlin-stdlib . Не следует исключать эти транзитивные зависимости, иначе могут возникнуть ошибки во время выполнения.

Комментарии:

1. Спасибо. » kotlin-stdlib-jdk8 является дополнением поверх kotlin-stdlib-jdk7 , а последнее является дополнением поверх kotlin-stdlib » был ответ, который я ищу. Как я упоминал в своем вопросе, я знаю, что jackson-module-kotlin было причиной ошибок.

2. Обратите внимание, что если jackson-module-kotlin использовать некоторые новые функции, добавленные в Kotlin 1.3, это не будет работать с зависимостью Kotlin 1.2.x во время выполнения.

Ответ №2:

kotlin-stdlib-common , kotlin-stdlib-jdk7 и kotlin-stdlib-jdk8 кажутся взаимоисключающими из того, что я мог видеть внутри jars. Вот почему вам нужен артефакт jdk7, даже если вы используете jdk8.

kotlin-stdlib-jdk7 Jar содержит только то, что было добавлено в JDK7, например, AutoCloseable и другие внутренние API. Это не включено в артефакт JDK8, который включает в себя только то, что добавлено в JDK8.

Если вы не используете глобальные функции use или closeFinally , ваш код должен нормально работать без артефакта jdk7, но нет реальной причины исключать этот jar ИМХО.