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