Multi-Modules Maven Project Tutorial

Create a Multi-Modules Project

  1. Create Parent Maven Project
$ mvn -B archetype:generate -DgroupId=com.taogen.demo -DartifactId=parent-project -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4
# or
$ mvn archetype:generate -DgroupId=com.taogen.demo -DartifactId=parent-project -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
  1. Create submodules
$ cd parent-project
$ mvn -B archetype:generate -DgroupId=com.taogen.demo -DartifactId=web -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4
$ mvn -B archetype:generate -DgroupId=com.taogen.demo -DartifactId=service -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4
  1. Configuring Parent Project’s pom.xml

3.1. Setting <packaging> to pom

$ cd parent-project
$ vim pom.xml

Add the following <packaging> configuration below the <artifactId> tag In the parent-project‘s pom.xml

<packaging>pom</packaging>

By setting the packaging to pom type, we’re declaring that the project will serve as a parent or an aggregator; it won’t produce further artifacts.

3.2. Configuring Parent Submodules

$ cd parent-project
$ vim pom.xml

Add the following <modules> configuration below the <version> tag In the parent-project‘s pom.xml

<modules>
<module>web</module>
<module>service</module>
</modules>
  1. Configuring Submodule Project’s pom.xml

In the individual submodules’ pom.xml, add the parent-project in the parent section.

$ vim web/pom.xml
$ vim service/pom.xml

Add the following <parent> configuration below the <moduleVersion> tag In the submodule project’s pom.xml

<parent>
<artifactId>parent-project</artifactId>
<groupId>com.taogen.demo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>

Inherent Parent Dependencies Version

  1. Declaring dependencies version in the parent project pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20211205</version>
</dependency>
</dependencies>
</dependencyManagement>
  1. Inherent dependencies version in Submodules pom.xml

By declaring version in the parent, all submodules using only the groupId and artifactId, and the version will be inherited

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
</dependencies>

if a child module needs to use a different version of a managed dependency, you can override the managed version.

<dependencies>
...
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>xxx</version>
</dependency>
...
</dependencies>
  1. Verifying Inherent dependencies version is working
$ cd parent-project
$ mvn clean package

Dependency Between Submodules

In this tutorial, the web module depends on the service module. You can add service module dependency in web module project pom.xml.

<dependency>
<groupId>com.taogen.demo</groupId>
<artifactId>service</artifactId>
<version>${project.parent.version}</version>
</dependency>

Notice: To avoid a circular dependency between submodules. A circular dependency occurs when a module A depends on another module B, and the module B depends on module A.

Testing in Spring Boot Multi-Modules Maven Project

Test All Submodules

  1. Configuring spring boot
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

or

<properties>
<!-- included spring-boot-starter-parent -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- custom properties -->
<spring-boot.version>2.6.4</spring-boot.version>
</properties>

<dependencyManagement>
<dependencies>
<!-- included spring-boot-starter-parent -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<!-- included spring-boot-starter-parent. For unit testing. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
</plugin>
</plugins>
</build>
  1. Running all submodule unit tests
$ cd parent-project
$ mvn test

References