In Gradle, how do I declare common dependencies in a single place?
In Maven there is a very useful feature when you can define a dependency in the <dependencyManagement>
section of the parent POM, and reference that dependency from child modules without specifying the version or scope or whatever.
What are the alternatives in Gradle?
You can declare common dependencies in a parent script:
ext.libraries = [ // Groovy map literal
spring_core: "org.springframework:spring-core:3.1",
junit: "junit:junit:4.10"
]
From a child script, you can then use the dependency declarations like so:
dependencies {
compile libraries.spring_core
testCompile libraries.junit
}
To share dependency declarations with advanced configuration options, you can use DependencyHandler.create
:
libraries = [
spring_core: dependencies.create("org.springframework:spring-core:3.1") {
exclude module: "commons-logging"
force = true
}
]
Multiple dependencies can be shared under the same name:
libraries = [
spring: [ // Groovy list literal
"org.springframework:spring-core:3.1",
"org.springframework:spring-jdbc:3.1"
]
]
dependencies { compile libraries.spring }
will then add both dependencies at once.
The one piece of information that you cannot share in this fashion is what configuration (scope in Maven terms) a dependency should be assigned to. However, from my experience it is better to be explicit about this anyway.
As of Gradle 4.6, dependency constraints are suggested in the documentation as the way to achieve this. From https://docs.gradle.org/current/userguide/declaring_dependencies.html#declaring_a_dependency_without_version:
A recommended practice for larger projects is to declare dependencies without versions and use dependency constraints for version declaration. The advantage is that dependency constraints allow you to manage versions of all dependencies, including transitive ones, in one place.
In your parent build.gradle
file:
allprojects {
plugins.withType(JavaPlugin).whenPluginAdded {
dependencies {
constraints {
implementation("com.google.guava:guava:27.0.1-jre")
}
}
}
}
Wrapping the dependencies block with a check for the Java plugin (... whenPluginAdded {
) isn't strictly necessary, but it will then handle adding a non-Java project to the same build.
Then in a child gradle project you can simply omit the verison:
apply plugin: "java"
dependencies {
implementation("com.google.guava:guava")
}
Child builds can still choose to specify a higher version. If a lower version is specified it is automatically upgraded to the version in the constraint.
It's a late reply, yet you might also want to have a look at: http://plugins.gradle.org/plugin/io.spring.dependency-management It provides possibility to import a maven 'bom', and reuse the definitions defined in the 'bom'. It's certainly a nice help when gradually migrating from maven to gradle ! Enjoying it right now.
io.spring.gradle:dependency-management-plugin
plugin has problems with new Gradle 3.x series but stable for 2.x series. For reference look to bug report Drop support for Gradle 3 #115
In case of Spring (main promoter of BOM usage) you may end with:
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath 'io.spring.gradle:dependency-management-plugin:1.0.0.RELEASE'
}
}
repositories {
mavenLocal()
jcenter()
}
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:Athens-SR3'
}
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
Note that io.spring.platform:platform-bom
have org.springframework.boot:spring-boot-starter-parent
as parent so it is compatable with Spring Boot
You can verify actual dependency resolution via:
$ gradle dependencies
$ gradle dependencies --configuration compile
$ gradle dependencies -p $SUBPROJ
$ gradle buildEnvironment
$ gradle buildEnvironment -p $SUBPROJ
or with task:
task showMeCache {
configurations.compile.each { println it }
}
Read official Soring blog post Better dependency management for Gradle to understand the reason of introducing io.spring.gradle:dependency-management-plugin
.