Building a Gradle Multi-Module Project

Large projects are usually split into multiple modules. Gradle’s multi-module support is very flexible; this article introduces the basic configuration and common practices.

Project Structure

my-project/
├── build.gradle          # root project
├── settings.gradle       # module declaration
├── module-api/           # API module
│   └── build.gradle
├── module-service/       # service module
│   └── build.gradle
└── module-web/           # Web module
    └── build.gradle

settings.gradle

Declare which submodules the project contains:

rootProject.name = 'my-project'

include 'module-api'
include 'module-service'
include 'module-web'

Root Project build.gradle

Configure all submodules uniformly:

// common configuration for all submodules
subprojects {
    apply plugin: 'java'

    group = 'com.example'
    version = '1.0.0'

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation 'junit:junit:4.13.2'
    }
}

To take effect only for the current project (not including submodules), use allprojects:

allprojects {
    // takes effect for all projects (including the root project)
}

Dependencies Between Modules

// module-service/build.gradle
dependencies {
    implementation project(':module-api')  // depends on another submodule
}

// module-web/build.gradle
dependencies {
    implementation project(':module-service')
}

Gradle automatically builds in dependency order.

Centralized Version Management

In the root build.gradle or in a separate file:

// gradle/versions.gradle
ext {
    versions = [
        spring: '5.3.20',
        junit : '4.13.2',
        guava : '31.1-jre'
    ]
}

Included in the root build.gradle:

apply from: 'gradle/versions.gradle'

subprojects {
    dependencies {
        implementation "com.google.guava:guava:${versions.guava}"
    }
}

Build Caching and Parallelism

# gradle.properties
org.gradle.caching=true
org.gradle.parallel=true
  • caching: reuse the output of previous builds
  • parallel: build independent modules in parallel

Building a Specified Module

# build only one module and its dependencies
gradle :module-web:build

# build all modules
gradle build

Sharing Configuration Between Modules

// takes effect only for certain modules
configure(subprojects.findAll { it.name.endsWith('-web') }) {
    apply plugin: 'war'
}

A small step forward every day takes you to a new height!

Author: Tang Moying

Source: /en/post/gradle-multimodule

License: this article is shared under "CC BY 4.0". Please credit the author and link back to the original when republishing.