Konubinix' opinionated web of thoughts

Maven Multi-Modules Project, Installing the Parent and Incremental Building

Fleeting

When creating a classical maven multi-modules project, you generally have the following hierarchy.

  • top level, declaring modules 1, 2, 3, …
    • module_1, declaring top level pom as parent
    • module_2, declaring top level pom as parent and depending on module_1
    • module_3, declaring top level pom as parent and depending on module_2
    • etc…

Because the top level declares module and is referred to as parent, it is a aggregator project as well as a parent project.

Say you want to build only module 2. You could use the --project flag.

mvn --projects module2 --also-make install

But in case you have a caching system based on folder changes, you might have to call this command again when a change in module_3 happened. Then you might want to copy only the needed module and the top level pom to the build process.

In that case, you might want to build the dependencies independently, using the following commands.

pushd module_1 && mvn install && popd
pushd module_2 && mvn install && popd

But in that case, you are likely to experience the top level pom not found in resolving the module_1 dependency. In the form

[ERROR] Failed to execute goal on project module_2: Could not resolve dependencies for project groupid:module_1:jar:version: Failed to read artifact descriptor for groupid:module_1:jar:version: Could not find artifact groupid:toplevel:pom:version -> [Help 1]

This is because when installing module_2, it needs to read the installed module_1 and its dependencies. The dependencies are described in the top level module, not yet installed.

Fortunately, you can install the top level project without building the subproject (this would break the incremental logic). Then the correct sequence is:

mvn install --non-recursive # to install the top level pom
pushd module_1 && mvn install && popd # to install the module_1, finds its top level pom in the upper directory (no need for installing the top level pom)
pushd module_2 && mvn install && popd # to install the module_2, finds its top level pom in the upper directory (no need for installing the top level pom), but also needs module_1 and then needs the installed top level pom to resolve its dependencies

For some reason, some people don’t like this logic and rather want to make the maven project inheritance and maven project aggregation described in separate poms.

In that situation, it is common to find the following hierarchy.

  • top level, declaring modules parent, 1, 2, 3, …
    • parent, being the maven parent
    • module_1, declaring parent pom as parent with relativePath=../parent
    • module_2, declaring parent pom as parent with relativePath=../parent and depending on module_1
    • module_3, declaring parent pom as parent with relativePath=../parent and depending on module_2
    • etc…

In that situation, you simply have to run the following command:

pushd parent && mvn install && popd # to install the parent pom
pushd module_1 && mvn install && popd # to install the module_1, finds its parent pom in the relativePath (no need for installing the parent pom)
pushd module_2 && mvn install && popd # to install the module_2, finds its parent pom in the relativePath (no need for installing the parent pom), but also needs module_1 and then needs the installed parent pom to resolve its dependencies