Currently there are (in my eyes) quite strange resolution strategies used in case a version conflict for a dependency is encountered. “Use the newest” and “use the closest” are the ones I saw several times now. However, none of these are actually related to the versions specified.
The most straightforward strategy I can think of is to use the most specific version.
In case of version ranges, take the intersection of the ranges. In case the intersection is empty, fail. * In case there is a specific version given somewhere in the dependency tree, use it. * Should there be a conflict between multiple specific versions and/or version ranges, fail. * In case there is no specific version specified use the newest of the range intersection.
Is there a way how I can teach gradle this strategy?
Currently the conflict resolution strategy used by Gradle is not user-tweakable. We plan to change this in the future.
Unfortunately, we’ve inherited from Ivy a strategy whereby the ‘newest’ detection is done both at the per-repository level, as well as at the time of conflict resolution. So before we can provide more powerful conflict resolution algorithms, we need to change this so that the complete list of available versions is exposed from the respository resolver layer. This will probably involve restricting support for custom Ivy resolvers and deprecating some existing DSL elements.
In summary, we do have more flexible and powerful conflict resolution as a goal, and we’re currently moving slowly in that direction. But we’re still a little ways off.