Force dependency versions across sub projects

I would like to force the version of common libraries (e.g. guava) across hundreds of Gradle subprojects. Currently I am accomplishing this through a plugin applied to all subprojects which enables failOnVersionConflict and then forces a list of dependencies:

project.configurations {
  all {
    resolutionStrategy {
      // fail eagerly on version conflict (includes transitive)
      failOnVersionConflict()
      force project.forcedVersions
    }
  }
}

This forces any version conflicts to be fixed by a developer instead of Gradle auto selecting the highest version. They are strict rules, but required due to the complex environments we are deploying to.

Is there a better way to maintain this? Some of the new dependency management features in Gradle 5.0 look compelling, like dependency alignment, but I am not sure if they satisfy this use case. It looks like the new rules often declare a minimum dependency version, but do not force it in the case where a transitive dependency pulls in a higher version. Am I still out of luck for a cleaner solution?

2 Likes

You probably already know, but Springs dependency management plugin should be matching your requirements closely. It’s quite a burden on larger numbers of sub-projects, though.

If I understood the new depenendency management features in Gradle 5 correctly, using enforcedPlatform should also force the versions (I only read the release notes, but didn’t try, though).

I’d very much be interested in a response from the Gradle team to this, too.

The spring plugin does cover what I need and more, I am hoping for a Gradle native solution.

The enforcedPlatform looks very close to what I want, but defining a virtual platform appears to have restrictions. For instance, all modules need to be on the same version, which makes sense for dependencies published together like jackson libraries, but not for a blessed set of random dependencies.

For what it’s worth, I found a marginally better solution in the docs using resolve rules: https://docs.gradle.org/current/userguide/customizing_dependency_resolution_behavior.html#sec:custom_versioning_scheme

Now a reason shows up in the insight report for why a version was used.

1 Like