this is my very simple gradle file:
val junit5Version = "5.3.2"
val junitPlatformVersion = "1.3.2"
plugins {
java
kotlin("jvm") version "1.3.11"
}
group = "group"
version = "1.0-SNAPSHOT"
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile(kotlin("stdlib-jdk8"))
testImplementation("io.strikt:strikt-core:0.17.1")
}
it has a dependency on kotlin 1.3.11, and a test dependency on strikt, which has a dependency on kotlin 1.3.10.
the for me totally unexpected result of this is that in my test classpath my kotlin dependency is downgraded to 1.3.10
here’s runtime:
runtime - Runtime dependencies for compilation 'main' (target (jvm)) (deprecated, use 'runtimeOnly ' instead).
\--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.11
and here is testCompileClasspath:
testCompileClasspath - Compile classpath for compilation 'test' (target (jvm)).
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.11 -> 1.3.10
| +--- org.jetbrains.kotlin:kotlin-stdlib:1.3.10
there is also testCompile which does not seem to be downgraded:
testCompile - Dependencies for compilation 'test' (target (jvm)) (deprecated, use 'testImplementation ' instead).
\--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.11
+--- org.jetbrains.kotlin:kotlin-stdlib:1.3.11
| +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.3.11
so now I’m wondering why it acts that way, and whats the best practice here.
ljacomet
(Louis Jacomet)
December 13, 2018, 1:29pm
2
You should run the dependencyInsight
task which can give a better idea of why the downgrade happens.
Something like: ./gradlew dependencyInsight --configuration testCompileClasspath --dependency kotlin-stdlib-jdk8
thanks for that, here’s the output:
~/Projects/mine/randolf% ./gradlew dependencyInsight --configuration testCompileClasspath --dependency kotlin-stdlib-jdk8
> Task :dependencyInsight
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.10
variant "compile" [
org.gradle.status = release (not requested)
org.gradle.usage = java-api
org.gradle.component.category = library (not requested)
Requested attributes not found in the selected variant:
org.jetbrains.kotlin.platform.type = jvm
]
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.10
\--- io.strikt:strikt-core:0.17.1
\--- testCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.11 -> 1.3.10
\--- testCompileClasspath
it shows that the reason for the downgrade is like i expected. still its very unexpected, and probably not what most people want.
also i just checked the same gradle file with gradle 4.10 and there it does not happen. here’s what gradle 4.10 does:
~/Projects/mine/gradle-test% ./gradlew dependencyInsight --configuration testCompileClasspath --dependency kotlin-stdlib-jdk8
> Task :dependencyInsight
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.11
variant "default+runtime" [
org.gradle.status = release (not requested)
Requested attributes not found in the selected variant:
org.gradle.usage = java-api
org.jetbrains.kotlin.platform.type = jvm
]
Selection reasons:
- Was requested
- By conflict resolution : between versions 1.3.11 and 1.3.10
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.11
\--- testCompileClasspath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.10 -> 1.3.11
\--- io.strikt:strikt-core:0.17.1
\--- testCompileClasspath
and seems to be the better solution.
Selection reasons:
- Was requested
ljacomet
(Louis Jacomet)
December 13, 2018, 2:15pm
5
For which version of Gradle is this not working? Before 4.10? 5.0?
ljacomet
(Louis Jacomet)
December 13, 2018, 2:43pm
6
I can explain the behaviour. It comes from the Kotlin plugin that is extremely lenient with the Kotlin library versions to use.
As can be seen in the plugin code , they use a prefer
constraint when they see a dependency without the version specified.
However the prefer
version constraint has evolved in terms of meaning in the recent Gradle versions. It is now really meant to be used as: “If no one else has an opinion, pick this version” and is usually combined with a require
or strictly
version range declaration to pick a specific version in the range should no other dependency express an opinion.
In your case, as soon as another module with a version enters the dependency graph, it means the prefer
gets ignored and thus you see a version downgrade.
The easiest solution is to add a version to your dependency declaration, by doing `compile(kotlin(“stdlib-jdk8”, “1.3.11”)) which effectively means your dependency has a version and it will be conflict resolved as expected.
ok thanks a lot. I will create a ticket in the kotlin youtrack instance then