Maven Project Inheritence and Project Aggregation

Project Inheritence

Lavish Jain
5 min readMay 8, 2023

The Super POM is one example of project inheritance, however you can also introduce your own parent POMs by specifying the parent element in the POM, as demonstrated in the following examples.

Let us reuse our previous artifact, com.mycompany.app:my-app:1.
And let us introduce another artifact, com.mycompany.app:my-module:1, in which we want to inherit the properties (dependencies, plugins, resources etc.) defined in pom.xml of com.mycompany.app:my-app:1, we can have com.mycompany.app:my-app:1 as parent in the pom.xml of com.mycompany.app:my-module:1.

<project>
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>

<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
</project>

If we want the groupId or the version of your modules to be the same as their parents, we can remove the groupId or the version identity of our module in its POM.

<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>

<artifactId>my-module</artifactId>
</project>

“relativePath” Tag for Parent POM

Maven doesn’t resolve the parent POM by searching in repositories first.
1.
If there is a pom.xml file in the parent folder, and if this file has the matching groupId/artifactId/version (GAV coordinate), it is classified as the project’s Parent POM.
2. If not, Maven reverts to the repositories

In case of Multimodule Projects, we place one maven project into another one.
Let us place my-module in the my-app folder, so the folder structure will look like this-

In this case, our previous pom.xml for my-module will work as by default it will look for parent pom in parent folder and it will find pom for my-app there.
Note that in this case there is no need to install the my-app pom into a repository as my-module will find the my-app pom in its parent folder and will not look into installed artifacts in the repository.
However, if the my-app project is configured as a dependency from other maven project, then my-app pom should be available in a repository too.
Also note that though my-module is now a part of my-app folder, but both are different maven artifacts having different poms and their own project structures. So if we’d need to build both these projects separately to have their respective artifacts updated in maven repository. Build only my-app project will not include my-module project build. This parent-child relationship is just for pom inheritence.

Now let’s have another maven project my-new-module again inside my-app folder parallel to my-module, so the folder structure will look like this-

In the pom of my-new-module, if we configure my-module as parent as we did before then it will look for my-module pom in parent folder that is my-app and it will not find it there so we’d somehow need to configure the relative path of parent pom and that’s where relativePath tag is used.

<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
<relativePath>../my-module/pom.xml</relativePath>
</parent>

<artifactId>my-new-module</artifactId>
</project>

Note that, we should only use relative paths that are available in every environment (mostly to a path within the same Git repository) to ensure the portability of our build.

Disable Local File Resolution

To skip the local file search and directly search the parent POM in Maven repositories, we need to explicitly set the relativePath to an empty value.

<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>external-project</artifactId>
<version>1</version>
<relativePath/>
</parent>

<artifactId>my-new-module</artifactId>
</project>

Project Aggregation

-> Project aggregation, also known as multi-module projects, is used to group related Maven projects together under a single parent project.
-> Instead of specifying the parent POM from the module, it specifies the modules from the parent POM.
-> The parent project contains a pom.xml file that defines common configuration settings and dependencies that can be shared by all child modules.
-> The child modules inherit the parent project’s pom.xml file, and when built, Maven automatically builds all child modules in the correct order.
-> If a Maven command is invoked against the parent project, that Maven command will then be executed to the parent’s modules as well.
-> Child modules will by default inherit parent’s pom without the need of explicitly putting parent tag in their poms.
-> Project aggregation is typically used when you have multiple related projects that need to be built and deployed together.

Steps required for Project Aggregation-

  • Change the parent POMs packaging to the value “pom”.
  • Specify in the parent POM the directories of its modules (children POMs).

For this project structure-

The POMs are as follows-

<project>
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>

<modules>
<module>my-module</module>
<module>my-new-module</module>
</modules>
</project>
<project>
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
<project>
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany.app</groupId>
<artifactId>my-new-module</artifactId>
<version>1</version>
</project>

Note that The value of <module> is the relative path from the com.mycompany.app:my-app:1 to its children POMs (by practice, we use the module's artifactId as the module directory's name).

For this project structure-

Parent Pom will be-

<project>
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>

<modules>
<module>../my-module</module>
<module>my-new-module</module>
</modules>
</project>

Project Inheritance vs Project Aggregation

  • Project aggregation is used to group related projects together and share common configuration settings and dependencies and you can build and deploy them together as a single unit, while project inheritance is used to define a hierarchical relationship between Maven projects and allow child projects to inherit and override configuration settings and dependencies from their parent projects.
  • Though in a project aggregation, all child modules are aggregated under the same parent project, and by default, they inherit the parent project’s configuration settings and dependencies. However, it’s generally recommended to include the parent tag in a child module’s pom.xml file in a project aggregation, as it makes the project structure more explicit and easier to understand for other developers who may be working on the project in the future. Hence we can have project aggregation as well as project inheritence together.
  • Also it is possible to have different parent POMs defined in the child modules of a Maven project than the parent POM defined for the overall project aggregation.
    Hence you can override this default parent POM by explicitly specifying a different parent POM in the child module’s pom.xml file and this child will inherit the properties of parent specified in parent tag not the parent in project aggregation scenario.

--

--