John Tipper
Navigate back to the homepage

Gradle – Managing Dependencies for Multi-Project Builds

John Tipper
July 19th, 2018 · 1 min read

When defining dependencies in Gradle, you’ll end up with a list in your build.gradle file of Maven Group-Artifact-Version items that you want to import, together with when you want access to them (compile, runtime etc). Here is an example, taken from the docs:

1// within build.gradle
2dependencies {
3 implementation 'org.hibernate:hibernate-core:3.6.7.Final'
4 api 'com.google.guava:guava:23.0'
5 testImplementation 'junit:junit:4.+'
6}

Now imagine that you have a multi-project build, perhaps as described in the previous post here. Each project has its own dependencies, many of which are common. How is best to deal with this?

If you’re using the Gradle Wrapper (and you should be), then your wrapper jar will be in a directory off the project root directory called gradle. This is one place where it might make sense to establish a convention for your project about where dependencies can be defined. Let’s create a file containing definitions of our dependencies as per the example above:

1// gradle/libraries.gradle
2ext {
3 hibernateCoreVersion = "3.6.7.Final"
4 guavaVersion = "23.0"
5 junitVersion = "4.+"
6
7 libs = [
8 hibernate-core: "org.hibernate:hibernate-core:$hibernateCoreVersion",
9 guava: "com.google.guava:guava:$guavaVersion",
10 junit: "junit:junit:$junitVersion"
11 ]
12}

Now, to enable each sub-project / module to be able to reference these, you’ll need to apply the gradle file to each project. This is done very simply by adding to the top level build.gradle file the following:

1// root project build.gradle
2subprojects {
3 apply from "$rootDir/gradle/libraries.gradle"
4}

Now, within each module’s build.gradle (or mymodule.gradle if your module is called mymodule and you renamed your module build files for clarity as I showed you here), you can do the following:

1// module's build.gradle
2dependencies {
3 implementation libs.hibernate.core
4 api libs.guava
5 testImplementation libs.junit
6}

The result is that all your dependencies are defined in one location but each module is free to include only the modules that are needed by that module.

More articles from John Tipper

Gradle Plugin Development – Functional Testing with Spock

Introduction to functional testing with Spock.

July 18th, 2018 · 1 min read

Gradle for large projects – customising multi-project build files

Customising Gradle multi-project builds by renaming the build.gradle file to be named after the project itself.

July 18th, 2018 · 1 min read
© 2018–2021 John Tipper
Link to $https://twitter.com/john_tipperLink to $https://github.com/john-tipperLink to $https://www.linkedin.com/in/john-tipper-5076395