【问题标题】: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 访问相同内容的任何建议。

【问题讨论】:

    标签: maven maven-2 maven-3 pom.xml


    【解决方案1】:

    @Sumit,

    Maven 在项目自己的groupId、artifactId 和version 之前检查&lt;parent&gt; 块及其包含的groupId、artifactId 和version。

    因此,您应该避免在 &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

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2012-07-24
        • 2013-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-02
        • 2020-05-14
        • 1970-01-01
        • 2016-06-12
        相关资源
        最近更新 更多