无法从父 pom.xml 解析子 pom.xml 中的 $project.version

Posted

技术标签:

【中文标题】无法从父 pom.xml 解析子 pom.xml 中的 $project.version【英文标题】:Unable to resolve $project.version in child pom.xml from parent pom.xml无法从父 pom.xml 解析子 pom.xml 中的 $project.version 【发布时间】:2015-01-07 15:04:49 【问题描述】:

我有一个项目层次结构:

A - pom.xml
|__ B - pom.xml
    |__ C - pom.xml

属性project.version在A中定义的pom.xml中定义。其他两个pom指定父标签和各自父pom对应的相对路径。

<parent>
        <groupId>com.GRP.id</groupId>
        <artifactId>ARTIFACT_ID</artifactId>
        <version>$project.version</version>
        <relativePath>../pom.xml</relativePath>
</parent>

这里的问题是 maven 无法解析 $project.version 并按原样使用它。从 A/B/C 执行时会引发以下异常:

[ERROR] The build could not read 1 project -> [Help 1]
org.apache.maven.project.ProjectBuildingException: Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for com.project_name.module_name:sub_module_name:[unknown-version]: Could not transfer artifact com.project_name.module_name:module_name:pom:$project.version from
to env-module_name-all-repos (REPO_URL): Illegal character in path at index 96: https://DEMO
/artifactory/env-module_name-all-repos/com/project_name/module_name/module_name/$project.version/module_name-$project.version.pom and 'parent.relativePath' points at wrong
local POM @ com.project_name.module_name:sub_module_name:[unknown-version], C:\WorkSpaces\Repository\sub_module_name\pom.xml, line 10, column 10

关于如何从子 POM 访问相同内容的任何建议。

【问题讨论】:

【参考方案1】:

@Sumit,

Maven 在项目自己的groupIdartifactIdversion 之前检查&lt;parent&gt; 块及其包含的groupIdartifactIdversion

因此,您应该避免在 &lt;parent&gt; 块内出现任何类似于 $... 的内容。相反的情况是可以的:父母的属性可以在 pom 文件的其他地方引用:

<project>

    <!-- parent's GAV: inspected first, cannot use tokens -->
    <parent>
        <groupId>com.GRP.id</groupId>
        <artifactId>parent-id</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <!-- project's GAV: inspected second, may reference parent -->
    <groupId>$parent.groupId</groupId>
    <artifactId>child-id</artifactId>
    <version>$parent.version</version>
    <properties>
        <some.prop.name>$parent.artifactId</some.prop.name>     <!-- parent-id -->
        <some.other.prop>$project.artifactId</some.other.prop>  <!-- child-id -->
    </properties>
</project>

这样想:如果您有一个儿子或女儿,您可能会选择以自己的名字命名他们 - 但在 您的孩子之后命名 是没有意义的 em> 自从你诞生以来!

希望对您有所帮助。

编辑:

让我们再看看你的示例 pom:

<parent>
    <groupId>com.GRP.id</groupId>
    <artifactId>ARTIFACT_ID</artifactId>
    <version>$project.version</version>      <!-- value doesn't exist yet -->
    <relativePath>../pom.xml</relativePath>
</parent>

所以在您孩子的 pom.xml 文件中,&lt;parent&gt; 块包含对 $project.version 的引用。但如上所述,该值尚不存在,因为 &lt;parent&gt; 块是我们要评估的第一件事。

如果你改变它如下,一切都会好起来的:

<parent>
    <groupId>com.GRP.id</groupId>
    <artifactId>ARTIFACT_ID</artifactId>

  <!-- EDIT 3A: parent.version is mandatory and must be a static value -->
    <version>1.0-SNAPSHOT</version>
    <relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.GRP.id</groupId>
<artifactId>CHILD_ARTIFACT_ID</artifactId>

<!-- EDIT 3B: project.version is optional, can be deleted
<version>$parent.version</version>
-->

编辑 2

最后一点信息。

请记住,当您最初在命令行上运行 mvn compile 时,您是从子 pom 的目录中运行的。

Maven 还不知道父级的 pom.xml 文件在哪里

它必须使用&lt;parent&gt;块来确定pom文件在哪里,然后才能读取文件的内容。

希望能澄清事情。

【讨论】:

感谢@333kenshin 的回复。让我重新表述我的问题。正如您所提到的,父块在子 pom.xml 中的任何其他块之前被解析,那么为什么 maven 无法解析父块中的$parent.version,因为显然与父 pom.xml 中提到的版本相同? 谢谢 333kenshin。还有一个问题,是否有任何解决方法可以在子 pom.xml 的父块中​​跳过 &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;。我们的项目很大,所以每次发布新版本时都很难更新每个 pom.xml 中的版本。 不幸的是,parent.version 是必需的,以便正确识别父级。另一方面,PROJECT 本身不需要声明版本 - 如果将其留空,它将继承父值包含的任何内容。 实际上,如果我跳过 标记或在父块中将其留空(),那么在这两种情况下它都无法编译并给出以下异常:@ 987654340@ @Sumit,注意不要将 'parent.version' 与 'project.version' 混淆。前者是强制性的,并且必须是静态值。后者可以是一种属性,甚至完全不存在。请参阅我的 sn-p 中的“EDIT 3”以获得说明。【参考方案2】:

我想分享我的工作,我使用的是 maven 3.5.2

    运行一个 mvn versions:set,它将更新父模块的版本和子模块中父模块的版本。

    构建聚合 pom 或父 pom,它应该构建所有子模块

    如果您有本地存储库或 nexus 存储库,则使用更新版本推送更改。

    现在所有子模块都有一个在步骤 1 中设置的固定父版本,我们可以将子模块用作跨多个项目的依赖项。

【讨论】:

【参考方案3】:

Maven 确实允许您在孩子的 POM 中使用 $project.version。它只是指通过查找您使用 relativePath 标记指定的父 POM 可以找到的父版本。

你碰巧在使用 Jenkins 吗?如果是这样,这是 Jenkins 中的一个已知问题。看看这个:https://issues.jenkins-ci.org/browse/JENKINS-23846

如果不是,您使用的是哪个版本的 Maven?

在不相关的旁注中,relativePath 的默认值为 ../pom.xml,因此如果您的项目遵循标准的多模块结构,则无需显式指定(就像您的示例 POM 所做的那样)。

【讨论】:

以上是关于无法从父 pom.xml 解析子 pom.xml 中的 $project.version的主要内容,如果未能解决你的问题,请参考以下文章

如何抑制从父 pom.xml 运行 maven-javadoc-plugin?

如何从父 pom 部署多个对等 webapp

pom.xml导入子模块失败

eclipse加载maven工程提示pom.xml无法解析

父标签上无法解析的父 POM

报错: eclipse加载maven工程提示pom.xml无法解析org.apache.maven.plugins:maven-resources-plugin:2.3.2