When Gradle does version conflict resolution on a ...
# dependency-management
g
When Gradle does version conflict resolution on a dependency, shouldn’t it align the version it chooses between runtimeClasspath and compileClasspath? I understand this could lead to runtime errors since the code is compiled against one but runs with another
c
Gradle 6.8 added that capability.
Copy code
java {
    consistentResolution {
        useCompileClasspathVersions()
    }
}
Manual reference
g
Thank you. This is a huge topic, I missed that in the docs
c
i routinely find new stuff in the docs myself 😉
😉 1
v
We all do 🙂
🙂 2
g
Does this also apply for Android projects? 😅
g
Yes, both the problem and the solution
Actually, the
java
snippet I’m not sure, but if it doesn’t work, the mentioned doc shows how you can do that to other configurations
c
it appears that the
consistentResolution
configuration is only available on the Java plugin extension (
java
).
but you can do this where needed:
Copy code
configurations {
        runtimeClasspath.shouldResolveConsistentlyWith(compileClasspath)
    }
👍 1
if you use that escape hatch, be sure to catch ancillary configurations such as tests, etc (the consistentResolution configuration does all that for you, for Java projects)
g
Also be aware that implementation of the consistent resolution is one-to-one, so you can set each configuration to resolve consistently with exactly one other configuration. If you have complex relationships of the configurations be careful to get what you really want. For example there method that configures each compileClasspath to resolve consistently with relevant runtimeClasspath but each pair is independent. So you get consistent versions between them in the main source set, in the test source set but not between main source set runtime/compile classpath and any resolvable configurations for the test classpaths. I got some strange behaviour with it and version locking but haven't managed to create good reproduce yet to file an issue( Maybe it's just in dependency locking though.
👍🏻 1
j
I think Consistent Resolution is on of the most “under promoted” feature right now. 😄 One pattern I find more and more useful (if you build a single application) is to identify the “application runtime classpath” - i.e. the Configuration that will be used by the application in the end - and make everything consistently resolve with that. I explain this in more detail here:

https://www.youtube.com/watch?v=YYWhfy6c2YQ&t=305s

And here I use it in a larger project setup. For standard JVM: https://github.com/jjohannes/gradle-project-setup-howto/blob/kotlin/gradle/plugins[…]ns/src/main/kotlin/org.example.consistent-resolution.gradle.kts And on top for Android: https://github.com/jjohannes/gradle-project-setup-howto/blob/android/gradle/plugin[…]rg.example.consistent-resolution-android-application.gradle.kts
💯 1
l
I guess the (bad) reason for not promoting it more is that we still have the idea to provide “global” consistency check, which would fail a build if a dependency was resolved to two different versions across configurations and projects. And the reason this would not be a mode is that you most likely want isolated islands of consistency and that forcing resolution to be consistent has too many gotchas across projects. Example of islands: checkstyle or spotbugs classpath vs. application classpath