5 Steps to Make Gradle Configuration Extreme Clean in a Multi-Module Project

Noah Hsu
Javarevisited
Published in
3 min readJul 12, 2024

Multi-module Gradle projects involve numerous tasks during the build process. Managing dependency version control, plugin usage, build logic, and more with Gradle proves to be a popular and effective approach. But, achieving these tasks requires a lot of configuration scripts, which can make the file more complicated, and more difficult for development. These steps in the article will guide you through a clean and efficient way to manage configuration files:

  1. extract version declaring in gradle.properties.
  2. define all plugins and repositories in settings.gradle.
  3. define all libraries in the allprojects.dependencyManagement in ./build.gradle.
  4. declaring dependency and plugin directly instead of using subproject in submodule.
  5. extract complex and common task config to extra files and apply wherever needed.

Take a look at this repository or refactor PR, if you can’t wait to find out how it looks.

Step by Step Demonstration

Step 1: Extract Version Declaration

Version declarations can be extracted into a gradle.properties file. Additionally, Gradle arguments can be defined as shown below:

./gradle.properties

Step 2: Define Used Plugins and Maven Source

All used plugins and the source Maven repository can be defined in a settings.gradle:

./setting.gradle

Step 3: Define Allprojects DependencyManagement

All the used libraries should be defined in a allprojects.dependencyManagement closure in build.gradle of the root module:

./build.gradle

in the dependencyManagement closure, we can first import the BOM of other dependencies project like spring-boot-dependencies and spring-cloud-dependencies. Then, we can declare the version of other used libraries.

Step4: Avoid Using subprojects {}

Declaring dependency and plugin directly instead of using subproject in build.gradle for sub-modules like:

./order/command-side/build.gradle

It can be more intuitive to declare the used plugin and dependencies in each project. Thanks to the dependencyManagement in the root module, we can use a simple form of the declaration here in the sub-project.

Step 5: Extract Related Configuration

Extract complex and common task config to extra files and apply them wherever needed.

In the above file ./order/command-side/build.gradle, the important script snippet

apply from: "$rootDir/gradle/jib.gradle"

will include an extra .gradle file, which we can group related config into one file. Let's take the ./gradle/jib.gradle for example:

./gradle/jib.gradle

In this way, we can make the .gradle file in the submodules/subprojects is very clean and more readable. Moreover, we can reuse these configurations in different places (e.g. order/query-side, payment/command-side, etc.).

My article will stay free and unlocked, but you can support and inspire me to write more by buying me a beer 🍺.

Your generosity fuels my passion for creating more content about Java and coding.

Don’t forget to share and clap for this article, and follow me on Medium for future tech stories. Thanks for your support and happy reading!

Summary

In conclusion, managing a multi-module Gradle project can be streamlined and elegant by adopting a structured approach to configuration. In this article, we propose a five-step method to centralize plugin and dependency version declarations and extract configurations into independent .gradle files. Besides, be cautious when using special methods to ensure the project-building logic straightforward and easy to manage. By following these steps, you can enhance the readability and maintainability of your multi-module Gradle projects.

Reference

--

--

Noah Hsu
Javarevisited

Java ServerSide Engr🚀, Focusing on Spring, Toggle system, Kafka, Event Sourcing, and CI/CD. Support my work with a 🍺. https://www.buymeacoffee.com/swbhcjhtyvv