Maven – Multi Modules
Guide to Build Multi Module Project using Maven
Maven Multi Module concept is used when we have one or more project dependent on one another or each other. At the end of this article, you will be able to create complex, multi-module project using Maven.
What is Multi Module Project?
A multi-module project is built from an aggregator POM that manages a group of sub-modules. The sub-modules are regular Maven projects, and they can be built separately or through the aggregator POM.
The significant advantage of using this approach is that we may reduce duplication.
When leveraging multi-modules, we can build our application’s modules in a single command and if the order matters, Maven will figure this out for us. Also, we can share a vast amount of configuration with other modules.
A multi-module project using Maven is defined by a parent POM referencing one or more sub-modules. We are going to create 4 maven project referencing below image as an example.
Example of Multi Module Project Structure
Create 4 maven projects following below project layout
POM of MasterApp (Parent module which has Packaging as POM)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.talksinfo</groupId> <artifactId>MasterApp</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <modules> <module>simple-webapp</module> <module>simple-web</module> <module>simple-service</module> </modules> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </pluginManagement> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
- Above
pom.xml
lists the project’s submodules. These modules are defined in themodules
element, and eachmodule
element points to a subdirectory of theMasterApp (Parent module)
directory. - The
dependencies
element adds JUnit 3.8.1 as a global dependency. Both the build configuration and the dependencies are inherited by all submodules. Using POM inheritance allows you to add common dependencies for universal dependencies like JUnit or Log4J.
POM of Simple-Service (Sub-module which has Packaging as JAR)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.talksinfo</groupId> <artifactId>MasterApp</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.talksinfo.service</groupId> <artifactId>simple-service</artifactId> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <testFailureIgnore>true</testFailureIgnore> </configuration> </plugin> </plugins> </pluginManagement> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
- In
simple-service
‘spom.xml
file, we see this module pointing a parent POM using agroupId
ofcom.talksinfo
, anartifactId
ofMasterApp
, and aversion
of0.0.1-SNAPSHOT
.
POM of simple-web (Sub-module which has Packaging as WAR)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.talksinfo</groupId> <artifactId>MasterApp</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>simple-web</artifactId> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.talksinfo.service</groupId> <artifactId>simple-service</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project>
- The
simple-web
module is the second sub-module referenced in theMasterApp
project. This web application project depends upon thesimple-service
module
POM of simple-webapp (Sub-module which has Packaging as EAR)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.talksinfo</groupId> <artifactId>MasterApp</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.talksinfo.ear</groupId> <artifactId>simple-webapp</artifactId> <packaging>ear</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.talksinfo</groupId> <artifactId>simple-web</artifactId> <version>0.0.1-SNAPSHOT</version> <type>war</type> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ear-plugin</artifactId> <version>3.0.1</version> </plugin> </plugins> </pluginManagement> </build> </project>
- The
simple-webapp
module is the third sub-module referenced in theMasterApp
project. This web application project depends upon thesimple-web
application module
Now it’s time to build our multi module project and before building let’s see about the reactor in Maven.
The Reactor
Maven handles multi-module projects using a concept “reactor”. This part of the Maven called “reactor” does the following:
- Collects all the available modules to build
- Sorts the projects into the correct build order
- Builds the selected projects in order
Reactor Sorting
Because modules within a multi-module build can depend on each other, it is important that the reactor sorts all the projects in a way that guarantees any project is built before it is required.
The following relationships are honoured when sorting projects:
- a project dependency on another module in the build
- a plugin declaration where the plugin is another module in the build
- a plugin dependency on another module in the build
- a build extension declaration on another module in the build
- the order declared in the
<modules>
element (if no other rule applies)
Command Line Options
No special configuration is required to take advantage of the reactor, however it is possible to customize its behavior.
The following command line switches are available:
--resume-from
– resumes a reactor the specified project (e.g. when it fails in the middle)--also-make
– build the specified projects, and any of their dependencies in the reactor--also-make-dependents
– build the specified projects, and any that depend on them--fail-fast
– the default behavior – whenever a module build fails, stop the overall build immediately--fail-at-end
– if a particular module build fails, continue the rest of the reactor and report all failed modules at the end instead--non-recursive
– do not use a reactor build, even if the current project declares modules and just build the project in the current directory
Building the Project
Now let’s run mvn clean install
command from the MasterApp
project. Once the Reactor figures out the order in which projects must be built, Maven then executes the specified goals for every module in the multi-module build and result appears something like below,
Successful build ends like:
Conclusion
In this article, we had a detailed look on following topics,
- What is multi module project in maven
- How it is structured,
- What reactor component does in maven for multi module project and
- How the multi module project is built