1.2 Transitive Dependency Management

Authored by Atri

Forcing Transitive Dependency Version Consistency

There are some cases where you may need to update dependencies in a fashion which is counter-intuitive to dependency control flow. In instances where this is necessary, it is possible to force Gradle to resolve dependencies at request-time as a different version that that which is defined.

// Usage
configurations.all {
	// Specific package
	forceDependencyVersion("com.somegroup.module", "package-dep", "1.2.34")
	// All packages in module
	forceDependencyVersion("com.somegroup.module", version = "1.2.34")
}

// Function declaration
fun Configuration.forceDependencyVersion(
	group: String,
	name: String? = null,
	version: String
) {
	resolutionStrategy.eachDependency {
		if (requested.group == group 
			&& (name == null || requested.name == name)) {
			useVersion(version)
		}
	}
}

By defining a declaration like what is provided above, you have the ability to overwrite the dependencies for all imported projects regardless of what they individually define. This is functionally a brute-force method to forcing package upgrades when its otherwise not possible to do so. It is recommended that you do not use this anywhere outside of top-level projects as abusing this tool can result in complications in project builds.

Danger

This will also functionally override the version of the dependency regardless of if the defined version is newer than the override or not, so keep this in mind.

Forcing Plugin Dependency Versions

While the above trick is greatly beneficial, it does not apply to the build environment (plugins) itself. There may additionally be cases where transitive dependencies in this scope need to be directly managed as well, but in order to get at these dependencies specifically we need to use a different solution.

buildScript {
	configurations.all {
		resolutionStrategy {
			// Force update declared package to specific version.
			force("com.somedependency.module:package-example:1.2.34")
		}
	}
}

The approach for this is far more vanilla relative to standard Gradle DSL code. Likewise, this functions in a similar capacity to the above script, which means this will also override the dependency regardless of version recency.