December 10, 2019

Spring Boot Initializr is the perfect starting point for creating a Spring Boot Gradle project from scratch. However it doesn’t provide an option for using a multi-module approach - which are the basic steps do make this transformation yourself?

Preparation

Let’s assume you’ve choosen a project with the following options on the Initializr Page:

  • Gradle

  • Java 8

  • spring-boot-starter-web as selected dependency

After the export the basic file structure looks like the following:

initial file structure

The build.gradle is already containing the specified dependencies.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
plugins {
        id 'org.springframework.boot' version '2.1.4.RELEASE'
        id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.it_surmann'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
        mavenCentral()
}

dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-web'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

For having something to see in the browser, let’s add WebController.java as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.it_surmann.multimodule;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
public class WebController {

    @RequestMapping("/")
    @ResponseBody
    public String home() {
        return "multimodule";
    }

}

So far, so good - after starting the application you should see the "multimodule" response in the browser (on localhost:8080 by default). How to transform this into a multi-module project?

Steps to modularization

  1. Extend the file structure

    First the file structure should be adjusted to split the code as desired. In this example we’re going to create the modules mm-base and mm-web - so the new file structure looks like this:

    extended file structure

  2. Replace settings.gradle to include the new modules

    1
    
    include 'mm-base', 'mm-web'
  3. Adjust build.gradle

    That’s the interesting part: the build.gradle needs to be adjusted for the multi-module approach. The spring-boot-starter-web can go into the base module, while spring-boot-starter-test needs to be available for every subproject - as your procject is going to have a high test coverage, right?!

    With the dependency type api a library is available in referencing modules as well. The java-library plugin works better with the structure we have now. There are some changes to the dependency management plugin in order to keep it working - more explanations on this here.

    So the final build.gradle file looks like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    
    buildscript {
        ext {
            springBootVersion = '2.1.4.RELEASE'
            rootProjectName = 'multi-module-demo'
            group = 'com.it_surmann'
            version = '0.0.1-SNAPSHOT'
        }
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        }
    }
    
    subprojects {
        apply plugin: 'java-library'
        apply plugin: 'io.spring.dependency-management'
    
        repositories {
            mavenCentral()
        }
    
        dependencyManagement {
            imports {
                mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
            }
        }
    
        dependencies {
            testImplementation 'org.springframework.boot:spring-boot-starter-test'
        }
    
        sourceCompatibility = '1.8'
    
        ext {
            projectName = "$rootProjectName-$project.name"
        }
    }
    
    project(':mm-web') {
        apply plugin: 'org.springframework.boot'
    
        bootJar {
            mainClassName = "com.it_surmann.multimodule.MultiModuleDemoApplication"
        }
    
        dependencies {
            api project(':mm-base')
        }
    }
    
    project(':mm-base') {
        jar {
            baseName = projectName
        }
    
        dependencies {
            api 'org.springframework.boot:spring-boot-starter-web'
        }
    }

Running the application you should see again the "multimodule" response!

Save time with Bootify

If you want to get your multi-module setup out-of-the-box, or just want to explore an example, check out Bootify.io. You can create your database model online, select advanced options like multi-module in the professional plan and then download your runnable Spring Boot prototype.

Contact