5

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.

gaurs
  • 575
  • 1
  • 5
  • 19

3 Answers3

14

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

333kenshin
  • 1,995
  • 12
  • 17
  • Thanks for the reply @333kenshin. Let me rephrase my question. As you mentioned that the parent block is resolved before any other block in the chiild pom.xml, so why maven is not able to resolve `${parent.version}` in the parent block as the same is clearly the version mentioned in the parent pom.xml? – gaurs Nov 11 '14 at 07:57
  • Thanks 333kenshin. Just one more question, is there any workaround to skip `1.0-SNAPSHOT` in the parent block of child pom.xml. Ours is a huge project so it becomes very difficult to update the version in each pom.xml every time a new release is in progress. – gaurs Nov 11 '14 at 08:14
  • 1
    Unfortunately not, the parent.version is mandatory in order to correctly identify the parent. On the other hand, the PROJECT itself doesn't need to declare version - if you leave it blank, it will inherit whatever the parent's value contains. – 333kenshin Nov 11 '14 at 08:23
  • Actually if I skip the tag or leave it blank () in the parent block then in both the cases its not able to compile and gives the following exception: `[FATAL] 'parent.version' is missing. @ line 13, column 12` – gaurs Nov 11 '14 at 08:31
  • @Sumit, be careful not to confuse 'parent.version' with 'project.version'. The former is mandatory and must be a static value. The latter can be a property, or even absent entirely. See "EDIT 3" in my snippet for clarification. – 333kenshin Nov 11 '14 at 08:35
1

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.

sethu
  • 11
  • 1
0

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.

neesh
  • 5,167
  • 6
  • 29
  • 32