First of all, I think Gradle is great. It does very well a lot of things. One of the things it just does not get along with is version range resolution. For how I understand it, this behaviour is inherited from Ivy, but it is nonetheless plain insane.
Suppose you are developing a project, which declares a dependency upon two libraries:
bar. Both of those dependencies use Google Guava.
foo declares compatibility with Guava
bar declares compatibility with Guava
[16.0, 18.0]. The most obvious behaviour is to pick the intersection of ranges and choose within, in this case,
[16.0. 17.0] should be selected).
By default, the fucking insane way of Gradle of resolving the overlapped ranges is to just grab the newest version declared in both ranges. In this case, Guava 18 would be used. What does it mean? It means that if there is at least one library that at some point partly breaks backwards compatibility, then your build will just break. A less insane resolution strategy can be forced by specifying
configurations.all. The new behaviour is: throw errors if the maximum declared version for a library is not always the same for all ranges in the dependency tree. The “error” (which is not an error, since there is version overlapping) can then be solved manually, wasting time, efforts, and portability. It is not possible, to the best of my knowledge, to force an automatic “select the highest version included in all ranges” strategy. This destroys the primary purpose of version ranges. If, by any chance, you know a way to tell Gradle to behave like it should, please let me know.