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 the modules element, and each module element points to a subdirectory of the MasterApp (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‘s pom.xml file, we see this module pointing a parent POM using a groupId of com.talksinfo, an artifactId of MasterApp, and a version of 0.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 the MasterApp project. This web application project depends upon the simple-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 the MasterApp project. This web application project depends upon the simple-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
Please follow and like us:
error