Understanding Maven’s “relativePath” Tag for a Parent POM – 了解Maven的“相对路径&8221;标签,为父级POM服务

最后修改: 2021年 9月 8日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

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.

在本教程中,我们将学习Maven的Parent POM解析。首先,我们会发现其默认行为。然后,我们将讨论定制它的可能性。

2. Default Parent POM Resolution

2.默认的母体POM分辨率

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:

如果我们想指定一个父POM,可以通过命名groupIdartifactId,version,即所谓的GAV坐标来实现。Maven并不通过先在仓库中搜索来解决父POM的问题。我们可以在Maven模型文档中找到详细内容,并总结出该行为。

  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:

在管理多模块项目时,将一个Maven项目放入另一个项目是最佳做法。例如,我们有一个聚合器项目,其GAV坐标如下。

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

因此,模块1的POM可以包括这一部分。

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

不需要将聚合器POM安装到版本库中。甚至不需要在聚合器POM中声明module1。但我们必须注意,这只适用于项目的本地检出(例如,在构建项目时)。如果该项目被解析为来自Maven资源库的依赖关系,那么父级POM在资源库中也应该是可用的。

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

我们必须确保聚合器的POM有匹配的GAV坐标。否则,我们会得到一个构建错误。

[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

3.定制父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:

如果父级POM不在父级文件夹中,我们需要使用relativePath标签来引用这个位置。例如,如果我们有第二个模块应该从module1继承设置,而不是从聚合器继承设置,我们必须命名同级文件夹。

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

当然,我们应该只使用每个环境中都有的相对路径(主要是指同一Git仓库内的路径),以确保我们构建的可移植性。

4. Disable Local File Resolution

4.禁用本地文件解析

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:

为了跳过本地文件搜索,直接搜索Maven仓库中的父POM,我们需要明确将relativePath设为空值。

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

每当我们从外部项目(如Spring Boot)继承时,这应该是一种最佳做法。

5. IDEs

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:

有趣的是,IntelliJ IDEA(当前版本:2021.1.3)配备了一个Maven插件,该插件在父级POM解析方面与外部Maven运行系统不同。与Maven的POM模式不同,它是这样解释relativePath标签的。

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

[…] Maven首先在当前构建项目的反应器中寻找父pom […] 。

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.

这意味着,对于IDE内部的解析,只要父项目被注册为IntelliJ Maven项目,父POM的位置就不重要。这对简单开发项目而不明确构建项目可能有帮助(如果它们不在同一个Git仓库的范围内)。但如果我们试图用外部Maven运行时来构建项目,就会失败。

6. Conclusion

6.结语

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.

在这篇文章中,我们了解到Maven不会首先通过搜索Maven仓库来解决父POM。而是在本地搜索,在继承外部项目时,我们必须明确停用这一行为。此外,IDE可能会额外解析到工作区的项目,这可能会导致我们在使用外部Maven运行时出现错误。

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

像往常一样,示例代码可在GitHub上获得