Maven can't get access to parent properties - maven

I have following structure:
parent-pom (pom)
|
- base-component (with <parent> parent-pom </parent>)(pom)
|
-- child-component (with <parent> base-component </parent>)(jar)
-- some-folder/another-child (with <parent> base-component </parent>)(jar)
In parent-pom I have properties with versions like
<properties>
<product-version>3.7.8</product-version>
</properties>
When I build child-component and use there ${product-version} - it is built without errors.
But when I trying to build another-child(with child-component as dependency) - maven can't read ${product-version} or throws an error Could not find artifact base-component even if I set <relativePath>.
I think the problem is folder between base-component and another-child, but I can't move it to level up.
Any ideas?

Make sure that the relative path is set correctly in the another-child module. Since it's under another directory, its parent base-component should be up by two directories:
<parent>
<groupId>...</groupId>
<artifactId>base-component</artifactId>
<version>...</version>
<relativePath>../../pom.xml</relativePath>
</parent>
Also make sure that in the base-component project, the module definition includes the additional path for another-child, so it should be something like:
<modules>
<module>child-component</module>
<module>some-folder/another-child</module>
</modules>
Before building another-child (or any other sub-module), try to build (mvn install) the whole project, starting at the root parent.

Try setting on the pom the project directory.
Parent:
<properties>
<main.basedir>${project.basedir}</main.basedir>
</properties>
Sibbling/children:
<properties>
<main.basedir>${project.parent.basedir}</main.basedir>
</properties>
children/ grandchildren:
<properties>
<main.basedir>${project.parent.parent.basedir}</main.basedir>
</properties>

Related

unable to resolve Maven dependency placeholder reference value

my project has dependencies on some framework jars:
<groupId>my-compamy</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
<dependency>
<groupId>my-company</groupId>
<artifactId>child-jar1</artifactId>
<version>2.0</version>
</dependency>
recently the framework team changed their packaging, in the repository, they put a parent pom (used to be separated child jars) like this:
<properties>
<reivison>2.0</revision>
</properties>
<groupId>my-company</groupId>
<artifactId>framework-parent</artifactId>
<packaging>pom</packaging>
<version>${revision}</version>
<modules>
<module>child-jar1</module>
</modules>
in the child-jar1 pom:
<parent>
<artifactId>framework-parent</artifactId>
<groupId>my-company</groupId>
<version>${revision}</version> <!-- can find the value! -->
</parent>
<artifactId>child-jar1</artifactId>
<packaging>jar</packaging>
When I build my-project, I got error message like:
... Failed to collect dependencies at my-company:child-jar1:jar:2.0.
... cuased by: could not find framework-parent:pom ${revision}
and the child-jars are not downloaded.
it looks that it is the placeholder in the child pom caused the problem: my-project could not resolve the placeholder value in the dependent(chiild-jar1)'s pom.
tried multiple approaches to resolve the referenced value from my-project side but nothing worked. Can this be resolved from my-project side without altering any dependency framework's setting? Please help.
There is a way to replace the palceholder with concrete value: add flatten-maven-plugin in the framework parent pom file build section (first to run) - this does not impact the framework's functionality but has to be done in the framework side. I gave this suggestion to the framework owner and they took it. It works.
Thanks to all comment providers!

Can modules referring to parent pom by relative path be depended on by 3rd parties?

I have a parent module, which defines its version as follows:
<groupId>org.group</groupId>
<artifactId>parent-id</artifactId>
<packaging>pom</packaging>
<version>${library.version}</version>
<properties>
<library.version>1.0.0</library.version>
</properties>
Then I have a sub module, which points to its parent as follows:
<parent>
<groupId>org.group</groupId>
<artifactId>parent-id</artifactId>
<version>${library.version}</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>child-id</artifactId>
<packaging>jar</packaging>
And I depend on it in my other projects like so:
<dependency>
<groupId>org.group</groupId>
<artifactId>child-id</artifactId>
<version>1.0.0</version>
</dependency>
This results in the following error for me:
Failed to read artifact descriptor for org.group:child-id:1.0.0: Failure to find org.group:parent-id:pom:${library.version}
Can this problem be solved without resorting to mvn versions:set in my multi module project to manage explicit versions in all poms?
/edit: currently solved this problem with a workaround that makes using mvn versions:set a little easier.

Maven project version as expression, not constant

I want to version my parent project differently than the rest of the modules that depend on it, for which I want to have common version.
This is since my parent is defining dependencyManagement, distributionManagement, buildManagement, *Management... Parent project really has quite different lifecycle than the rest of the modules. It updates seldomly. It would almost never update if not changing the version for the rest of the modules.
I basically want to do
<parent>
<groupId>com.mycompany</groupId>
<artifactId>myparent</artifactId>
<version>5</version>
</parent>
<groupId>com.mycompany</groupId>
<artifactId>myApp</artifactId>
<version>${next-version}</version>
and in the parent
<groupId>com.mycompany</groupId>
<artifactId>myparent</artifactId>
<version>5</version>
<properties>
<next-version>1.2.1-SNAPSHOT</next-version>
</properties>
While typing this it occurred to me - should this be done by having intermediate parent?
Well, it turns out that Maven itself has multiple levels of inheritance. They are in fact using intermediate parent poms. They have something like this:
org.apache:apache:16 > org.apache.maven:maven-parent:26 > org.apache.maven:maven:3.3.1-SNAPSHOT > org.apache.maven:maven-core:{inherited.from.parent}.

How to setup circular reference in maven modules?

I have this problem with building a maven project...
A mvn project parent is set like this:
<groupId>com.company.system.ping</groupId>
<artifactId>system-ping</artifactId>
<name>system-ping</name>
<parent>
<artifactId>parent_lvl_1</artifactId>
<groupId>com.company.system</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
Then I look for said parent's POM and find this:
<groupId>com.company.system</groupId>
<artifactId>parent_lvl_1</artifactId>
<packaging>pom</packaging>
<name>_proj_test</name>
<version>1.0-SNAPSHOT</version>
<parent>
<artifactId>parent_lvl_0</artifactId>
<groupId>com.company</groupId>
<version>1</version>
</parent>
I finally look at the first parent and see this:
<groupId>com.company</groupId>
<artifactId>parent_lvl_0</artifactId>
<packaging>pom</packaging>
<name>_main</name>
<version>1</version>
<description>The whole Projects</description>
Now I check the modules:
<modules>
<module>../_proj_test</module>
...
</modules>
The first parent module is referencing a child! So when I try
mvn install
on '_main' I get this:
[ERROR] The project com.company.system:_proj_test:1.0-SNAPSHOT (C:\...\pom.xml) has 1 error
[ERROR] Non-resolvable parent POM: The repository system is offline but the artifact com.company:_main:pom:1 is not available in the local repository. and 'parent.relativePath' points at wrong local POM # line 4, column 10 -> [Help 2]
[ERROR]
I translate this to: you parent requieres a module which requires you back. If I comment out everything in modules I can install everything correctly but this is NOT OK for me! How can I build the parent without building the module dependencies?
Thank you!
The config looks very weird to me, mainly because your '_proj_test' which is a child for '_main' is located on the same level.
How can I build the parent without building the module dependencies?
Try mvn -N install.
As for the project structure, I'd do it in such a way:
1) $basedir with '_main' pom.xml which should contain this
<modules>
<module>_proj_test</module>
</modules>
2) $basedir/_proj_test with '_proj_test' pom.xml which should contain this
<modules>
<module>system-ping</module>
</modules>
3) $basedir/_proj_test/system-ping with 'system-ping' pom.xml (with correct groupId of parent - com.company.system instead of com.company)

Warning on using project.parent.version as the version of a module in Maven 3

In maven multi-module projects where I want each of the modules to always keep the same version as the parent, I've typically done something like the following in the module's pom.xml:
<parent>
<groupId>com.groupId</groupId>
<artifactId>parentArtifactId</artifactId>
<version>1.1-SNAPSHOT</version>
</parent>
<groupId>com.groupId</groupId>
<artifactId>artifactId</artifactId>
<packaging>jar</packaging>
<version>${project.parent.version}</version>
<name>name</name>
Since I started using maven 3.0-alpha-5, I get the following warning for doing so.
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.groupid.artifactId:name:jar:1.1-SNAPSHOT
[WARNING] 'version' contains an expression but should be a constant. # com.groupid.artifactId:name::${project.parent.version}, /Users/whaley/path/to/project/child/pom.xml
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
I'm curious to know what the real problem with tying a module's version to the parent version is, if any? Or is this a case of a general warning when any expression, regardless of whether it's project.parent.version, is used for the version element.
I'm curious to know what the real problem with tying a module's version to the parent version is, if any? Or is this a case of a general warning when any expression, regardless of whether it's project.parent.version, is used for the version element.
Well, that would be easy to test. Because I was curious, I just did it for you using the following pom:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<groupId>com.mycompany</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.mycompany</groupId>
<artifactId>module</artifactId>
<version>${myversion}</version>
<name>module</name>
<url>http://maven.apache.org</url>
<properties>
<myversion>1.0-SNAPSHOT</myversion>
</properties>
...
</project>
And maven is indeed complaining:
[WARNING] 'version' contains an expression but should be a constant. # com.mycompany:module:${myversion}, /home/pascal/Projects/maven-maven3-testcase/module/pom.xml
To be honest, I think that maven is right here, it doesn't make much sense to use a property for the <version> element (at least not for project.version) and it's nice to have maven complaining about it.
And if you want to use the parent pom version in sub-modules, just remove the <version> tag from the child poms, they will inherit the version from the parent. What you are currently doing is unnecessary.
I might be late here to discuss on this. I got a simple solution for this WARNING.
First of all, if you want that all child modules will take same version as parent, then you just remove <version> tag from child POM and as you include <parent> in child POM, that should be there.
In absence of <version> in child POM, it will automatically take Parent POM version.
Now if you want to use property in parent POM version and want to get the same in all child-modules, you can go through as follow.
There is no limitation on using property in <version> part of parent or child POM. But if you use your own xml tag for specifying that or you use your own property, then WARNING comes, (although this is just warning, everything works as expected).
But if you want to get rid of this WARNING, you can follow these steps:
Create <properties> inside POM.xml as below
<properties>
<revision>1.0.0</revision> <!-- Put your version -->
</properties>
In <version> of the POM.xml, put as follow
<version>${revision}</version>
Sample code snippet (for multi-module project):
<groupId>abc.xyz</groupId>
<artifactId>pqr</artifactId>
<!-- <version>1.0.0</version> -->
<version>${revision}</version>
<packaging>pom</packaging>
<description>Parent POM</description>
<properties>
<revision>1.0.0</revision>
</properties>
Note: Instead of <revision>, if you use any other name (for example, <my.version>), you will face that WARNING
Now if you want to pass version during mvn deploy, you can use mvn deploy "-Drevision=1.0.0-SNAPSHOT" and similarly for mvn install also.
Now if above configuration, you want to use as Parent POM, and you want to use same version in all child module, that can also be done. In each child module POM, use below
<parent>
<groupId>abc.xyz</groupId>
<artifactId>Parent</artifactId>
<!-- <version>1.0.0</version> -->
<version>${revision}</version>
</parent>
<groupId>abc.xyz</groupId>
<artifactId>Child</artifactId>
<!-- <version>1.0.0</version> --> <!-- Automatically inherit parent POM version -->
<name>Demo</name>
For reference, you can go through maven multi module setup
It seems that the warning is correct. See MNG-4717: "the pom that gets deployed will not have the property value resolved, so
anyone depending on that pom will pick up the dependency as being the
string uninterpolated with the ${ } and much hilarity will ensue in your
build process." "However, if one uses flatten-maven-plugin the deployed pom gets a resolved value."

Resources