A team migrates a service from Maven to Gradle, keeping the same declared dependency versions. A transitive dependency that resolved one way under Maven resolves to a different version under Gradle, and a test that passed before now fails. Why would the same declared dependencies produce two different classpaths?
Maven and Gradle apply genuinely different default rules when two paths in the dependency graph request different versions of the same artifact. Maven's rule is nearest wins: whichever declaration sits closest, by depth, to the project's own POM is kept, regardless of whether it's newer or older. Gradle's default is the opposite: highest wins — it compares the requested versions directly and keeps whichever one is numerically greater, with no regard for how deep in the tree it was requested from. The same set of declared dependencies can walk the same graph and still land on two different resolved versions, because the two tools aren't asking the same question when they hit a conflict — one asks "which declaration is closer," the other asks "which version is bigger."