Multi-Module Maven Projects

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

Overview

For guidelines on when it is appropriate to use modules, and when separate projects, see "When We Should Use Modules ?" section.

The Reactor

When We Should Use Modules?

Two major benefits of a multi-module project are that all the parts can be built with a single command, and Maven handles the correct build order.

Modules and Versions

Different modules of the same project can have different versions, or they can all share the parent's version.

In case all modules evolve keeping maintaining their versions in lockstep, that version is specified in the parent POM.

if the version of the modules evolve independently, this can be made clear by specifying the parent POM version to be 0, and have each module POM specify its module's version, independently.

POM Structure

The Parent POM

A multi-module project is defined by a parent POM referencing one or more submodules. The essential elements are the packaging, which is of type "pom", and the list of modules.

<project>
    ...
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>

    <packaging>pom</packaging>

    ...
    <modules>
        <module>module1</module>
        <module>module2</module>
    </modules>
    ...
</project>

The "pom" packaging indicates that the single purpose of this (top-level) project is to provide a container Project Object Model.

The group ID will be shared with the modules.

The artifact ID does not really matter, it can be conventionally set to "maven-root". However, if the project is imported in IntelliJ IDEA, the IDE will use this value as the name of the project, so from this perspective, it makes sense to use a unique, user-friendly name.

For considerations on the version, see "Modules and Versions" section.

Each <module> element corresponds to a subdirectory of the top level project directory. Maven will look into these subdirectories for pom.xml files, and it will add the modules to the list of Maven projects included in a build. Each module will have its own independent source hierarchy.

The rest of the parent POM includes settings to be inherited by all modules. This is where common plug-ins (<pluginManagement>) and dependencies (<dependencyManagement>) should be declared.

The Module POM

The central element of a module POM, which designates it as a module of a larger project, is the <parent> element, which specifies the coordinates (groupId, artifactId and version) of the parent. Since we recommend a conventional value for the parent's version ("0"), the parent section should look similar to:

<project>
    ...
    <parent>
        <groupId>...</groupId>
        <artifactId>...</artifactId>
        <version>0</version>
    </parent>
    ...
</project>

Note that the <project> root does not need to contain a <groupId>, as it is inherited from the parent, and thus redundant. It is logical for modules to share their groupID with the parent.

However, the <artifactID> must be present, as it uniquely identifies the model.

Depending on the versioning model in use, the version may not be specified (in which case the modules inherits the parent's version), or it is specified, and that dictates the version of the module, independently of other modules.

Multi-Module Projects and IntelliJ IDEA

Create the POM files first, then import recursively in IntelliJ.