Unable to resolve ${project.version} in child pom.

2019-05-26 11:58发布

I have a project hierarchy as :

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

The property project.version is defined in pom.xml defined in A. Other two pom's specify the parent tag and the corresponding relative path to the respective parent pom's.

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

The issue here is that maven is not able to resolve ${project.version} and is using it as is. This is throwing the following exception when executed from 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

Any suggestion on how to access the same from child POMs.

3条回答
欢心
2楼-- · 2019-05-26 12:02

Maven does allow you to use ${project.version} in the child's POM. It simply refers to the parent's version which it can find by looking for the parent POM that you specify using the relativePath tag.

Do you happen to be using Jenkins? If so, this is a known issue in Jenkins. Take a look at this: https://issues.jenkins-ci.org/browse/JENKINS-23846

If not, what version of Maven are you using?

On an unrelated side note, the default value for the relativePath is ../pom.xml so you don't need to explicitly specify that (like your sample POM does) if you project follows the standard multi-module structure.

查看更多
男人必须洒脱
3楼-- · 2019-05-26 12:09

I would like to share my work around, i was using maven 3.5.2

  1. Run a mvn versions:set which will update the version of the parent and the versions of parent in the child modules.

  2. Build the aggregate pom or parent pom, which should build all the child modules

  3. If you have a local repository or a nexus repository push the changes with the updated versions.

  4. Now all the child modules have a fixed parent version which was set in step 1, we can use the child modules as dependency across multiple projects.

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-05-26 12:11

@Sumit,

Maven inspects the <parent> block and its contained groupId, artifactId, and version before the project's own groupId, artifactId and version.

So you should avoid anything that looks like ${...} inside the <parent> block. The reverse situation is OK though: parent's properties can be referenced elsewhere in the pom file:

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

Think of it this way: if you have a son or daughter, you might choose to name them after yourself - but it would make no sense to name you after your child since you came into existence first!

Hope that helps.

EDIT:

Let's look at your example pom again:

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

So in your child's pom.xml file, the <parent> block contains a reference to the ${project.version}. But as mentioned above, that value doesn't exist yet since the <parent> block is the first thing we're evaluating.

If you change it as follows, things will be fine:

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

EDIT 2

One last bit of info.

Remember, when you initially run mvn compile on the command line, you're running from the directory of the child pom.

Maven doesn't yet know where the pom.xml file of the parent is.

It has to use the <parent> block to figure out where the pom file is, only then can it read the contents of the file.

Hope that clarifies things.

查看更多
登录 后发表回答