简体   繁体   中英

Why does Kotlin JDK8 also include Kotlin JDK7 on the classpath?

I'm using Kotlin to build a web service and I stumbled upon what I consider to be a strange curiosity. With this 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"
}

I get this error during compilation:

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)

OK, no problem, jackson-module-kotlin is pulling in the kotlin 1.3 dependencies. I can exclude them. But the bit that caught my attention was the second line. kotlin-stdlib-jdk8 is also pulling in kotlin-stdlib-jdk7 . In fact, I can exclude it and everything still runs as expected:

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

Why is kotlin-stdlib-jdk8 pulling onto my classpath the seemingly unnecessary kotlin-stdlib-jdk7 ?

The warning you see during the compilation happens because jackson-module-kotlin:2.9.8 dependency apparently brings kotlin-stdlib:1.3.10 into the classpath and that version overrides your declared dependency on 1.2.71. To avoid warning you should either migrate your project to Kotlin 1.3.x or downgrade jackson-module-kotlin dependency to some previous version which depends on Kotlin 1.2.x.

kotlin-stdlib-jdk8 is an addition on top of kotlin-stdlib-jdk7 , and the latter is addition on top of kotlin-stdlib . You should not exclude these transitive dependencies, otherwise you might get runtime errors.

The kotlin-stdlib-common , kotlin-stdlib-jdk7 , and kotlin-stdlib-jdk8 seem to be mutually exclusive from what I could see inside the jars. That's why you need the jdk7 artifact even if you use the jdk8.

The kotlin-stdlib-jdk7 jar only contains things that were added in JDK7 like AutoCloseable and other internal apis. This is not included in the JDK8 artifact, which only include things added in JDK8.

If you don't use the use or closeFinally global functions, your code should work fine without the jdk7 artifact, but there is no real reason to exclude this jar IMHO.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM