I'm using Kotlin `2.1.10` in my project. Transitiv...
# gradle
r
I'm using Kotlin
2.1.10
in my project. Transitive dependencies are bringing in
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21
and
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21
. Is it appropriate to force them up to the same version as so:
Copy code
configurations.all {
    resolutionStrategy {
      force("org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.1.10")
      force("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.10")
    }
  }
t
Yes, KGP does kind of the same via dependency substituion:
Copy code
resolutionStrategy.dependencySubstitution {
        if (kotlinStdlibDependency.name != KOTLIN_STDLIB_JDK7_MODULE_NAME) {
            it.substitute(it.module("org.jetbrains.kotlin:kotlin-stdlib-jdk7"))
                .using(it.module("org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlinStdlibDependency.version}"))
                .because("kotlin-stdlib-jdk7 is now part of kotlin-stdlib")
        }

        it.substitute(it.module("org.jetbrains.kotlin:kotlin-stdlib-jdk8"))
            .using(it.module("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinStdlibDependency.version}"))
            .because("kotlin-stdlib-jdk8 is now part of kotlin-stdlib")
    }
I am curious why it does not work in your case 🤔
forgot that it does not work for transitive dependencies
v
Both are not really appropriate ways to control versions of transitive dependencies. The former is a very hard hammer meant for much more serious cases. The latter is usually not for controlling versions, but to substitute one dependency by a completely different one. Also if I look at the becauses in the latter it seems an exlcude would be more appropriate and Kotlin should use capabilities in Gradle Module Metadata to force a conflict in such cases by making the
kotlin-stdlib
artifact also provide the capabilities of the jdk7 and jkd8 artifacts.
If you want to control versions of transitive dependencies and are not using a platform for that, the proper way is to use dependency constraints like
Copy code
dependencies {
    constraints {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.1.10")            
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.10")
    }
}
t
but to substitute one dependency by a completely different one.
Not entiirely true as all the code was merged into
kotlin-stdlib
v
But as I said, in this case a capability conflict that is properly resolved would be cleaner semantics
r
It's always bothered me that I was specifying a specific configuration
implementation
there - is that not an issue?
v
Not entiirely true as all the code was merged into
kotlin-stdlib
But your rule does not substitute
kotlin-stdlib-jdk7
by
kotlin-stdlib
which it then probably should do 😉
t
this is done to support JPMS case sad panda
since Kotlin 1.8.0
-jdk8
and
-jdk7
are empty artifacts
but they are still being published
v
It's always bothered me that I was specifying a specific configuration
implementation
there - is that not an issue?
Most probably not. Maybe if you have that problem in an
api
dependency and resolve the
apiElements
configuration where
implementation
is not evolved or similar, but I would neglect that or just add a second configuration then. That
force
is really a very heavy hammer that should be avoided if possible. Iirc e.g. the "lovely" Spring Dependencymanagement Plugin uses it or something on the same level. And it very often was a source of "why the hell does this strict version not work" or "where the hell is this version constraint coming from" and so on, as that is a very low-level thing that is also not properly represented in build scans or
dependencies
output or
dependencyInsight
output. And if you would use a capability conflict like I suggested for this case, you would btw. also not have the problem with the configuration as that would again be for all, but working cleanly.
since Kotlin 1.8.0
-jdk8
and
-jdk7
are empty artifacts
Oh, I see, and thus also not the capability conflict, that's bad. I wonder that the artifacts are not version-aligned automatically. I was under the impression that Kotlin uses proper version aligning to ensure the artifacts are of the same version, but obviously it does not, maybe that is the bug then.
But I guess if you just use the Kotlin BOM as platform, it should at least improve it on consumer side, so
Copy code
dependencies {
    implementation(platform("org.jetbrains.kotlin:kotlin-bom:2.1.10"))
}
r
I'd missed there's a bom. I'll use that, thanks
👌 1
t
I wonder that the artifacts are not version-aligned automatically.
That is because
kotlin-stdlib
is a transitive dependency to
-jdk7
which a transitive dependency for
-jdk8
v
Do you know whether there is an open issue to add the alignment metadata to the artifacts @tapchicoma? I don't find one, but not sure what I would search
> I wonder that the artifacts are not version-aligned automatically.
That is because
kotlin-stdlib
is a transitive dependency to
-jdk7
which a transitive dependency for
-jdk8
How is that a reason to not align the versions?
t
I vaguly recall it right now but there where some edge-cases
hm, please open an issue for improvement
👌 1
v
That should just make sure that all artifacts that should have the same version do have the same version, to prevent exactly what happened to Rob
r
> It's always bothered me that I was specifying a specific configuration implementation there - is that not an issue?
Most probably not.
Maybe if you have that problem in an api dependency and resolve the apiElements configuration where implementation is not evolved or similar, but I would neglect that or just add a second configuration then.
I suppose
api
,
runtime
,
testRuntime
and
testImplementation
all basically inherit from
implementation
, so I can stop worrying about it and just use that. Thanks.
v
runtime
and
testRuntime
do not exist since years.
implementation
extends from
api
testImplementation
extends from
implementation
But neither of these you resolve.
implementation
though lands in
compileClasspath
,
runtimeClasspath
,
testCompileClasspath
, and `testRuntimeClasspath`so a constraint or platform declared on it should work for all your needs usually unless you have additional things.
please open an issue for improvement
https://youtrack.jetbrains.com/issue/KT-76006
thank you color 1