Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll learn about the Parent POM resolution of Maven. First, we’ll discover the default behavior. Then, we’ll discuss the possibilities to customize it.

2. Default Parent POM Resolution

If we want to specify a parent POM, we can do this by naming groupId, artifactId, and version, the so-called GAV coordinate. Maven doesn’t resolve the parent POM by searching in repositories first. We can find the details in the Maven Model Documentation and sum up the behavior:

  1. If there is a pom.xml file in the parent folder, and if this file has the matching GAV coordinate, it is classified as the project’s Parent POM
  2. If not, Maven reverts to the repositories

Placing a Maven project into another one is the best practice when managing Multi-Module Projects. For example, we have an aggregator project with the following GAV coordinate:

<groupId>com.baeldung.maven-parent-pom-resolution</groupId>
<artifactId>aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>

We could then place the module into the subfolder and refer to the aggregator as a parent:

module1

So, the module1 POM could include this section:

<artifactId>module1</artifactId>
<parent>
    <groupId>com.baeldung.maven-parent-pom-resolution</groupId>
    <artifactId>aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</parent>

There is no need to install the aggregator POM into a repository. And there is even no need to declare module1 in the aggregator POM. But we must be aware that this is only applicable for local checkouts of a project (e.g. when building the project). If the project is resolved as a dependency from a Maven repository, the parent POM should be available in a repository too.

And we have to ensure, that the aggregator POM has the matching GAV coordinate. Otherwise, we’ll get a build error:

[ERROR]     Non-resolvable parent POM for com.baeldung.maven-parent-pom-resolution:module1:1.0.0-SNAPSHOT:
  Could not find artifact com.baeldung.maven-parent-pom-resolution:aggregator:pom:1.0-SNAPSHOT
  and 'parent.relativePath' points at wrong local POM @ line 7, column 13

3. Customizing the Location of the Parent POM

If the parent POM is not located in the parent folder, we need to use the relativePath tag to refer to the location. For example, if we have a second module that should inherit the settings from module1, not from the aggregator, we must name the sibling folder:

module2
<artifactId>module2</artifactId>
<parent>
    <groupId>com.baeldung.maven-parent-pom-resolution</groupId>
    <artifactId>module1</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>../module1/pom.xml</relativePath>
</parent>

Of course, 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.

4. 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:

<parent>
    <groupId>com.baeldung</groupId>
    <artifactId>external-project</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <relativePath/>
</parent>
external

This should be a best practice whenever we inherit from external projects like Spring Boot.

5. IDEs

Interestingly, IntelliJ IDEA (current version: 2021.1.3) comes with a Maven plugin that differs from external Maven runtimes concerning the Parent POM resolution. Deviating from Maven’s POM Schema, it explains the relativePath tag this way:

[…] Maven looks for the parent pom first in the reactor of currently building projects […]

That means, for IDE-internal resolution, the position of the parent POM doesn’t matter as long as the parent project is registered as an IntelliJ Maven Project. This might be helpful to simply develop projects without explicitly building them (if they are not in the scope of the same Git repository). But if we try to build the project with an external Maven runtime, it will fail.

6. Conclusion

In this article, we learned that Maven does not resolve parent POMs by searching Maven repositories firstly. It rather searches for it locally, and we explicitly have to deactivate this behavior when inheriting from external projects. Furthermore, IDEs might additionally resolve to projects in the workspace, which may result in errors when we use external Maven runtimes.

As always, the example code is available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – Maven (eBook) (cat=Maven)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.