Maven version with a property - java

I have big Maven (Tycho) project witch about 400 plug-ins.
We have specified version of application in each POM file.
Is there a way how to specify the version for all POM:s only on one place?
I would expect some think like:
<properties>
<buildVersion>1.1.2-SNAPSHOT</buildVersion>
</properties>
....
<version>${buildVersion}</version>
We have parent pom.xml:
<modelVersion>4.0.0</modelVersion>
<groupId>company</groupId>
<artifactId>build.parent</artifactId>
<version>1.1.2-SNAPSHOT</version>
<packaging>pom</packaging>
Then in each POM is reference to parent POM:
<parent>
<artifactId>build.parent</artifactId>
<groupId>company</groupId>
<relativePath>../build.parent/pom.xml</relativePath>
<version>1.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>company</groupId>
<artifactId>artifact</artifactId>
<version>1.1.2-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>

If you have a parent project you can set the version in the parent pom and in the children you can reference sibling libs with the ${project.version} or ${version} properties.
If you want to avoid to repeat the version of the parent in each children: you can do this:
<modelVersion>4.0.0</modelVersion>
<groupId>company</groupId>
<artifactId>build.parent</artifactId>
<version>${my.version}</version>
<packaging>pom</packaging>
<properties>
<my.version>1.1.2-SNAPSHOT</my.version>
</properties>
And then in your children pom you have to do:
<parent>
<artifactId>build.parent</artifactId>
<groupId>company</groupId>
<relativePath>../build.parent/pom.xml</relativePath>
<version>${my.version}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>company</groupId>
<artifactId>artifact</artifactId>
<packaging>eclipse-plugin</packaging>
<dependencies>
<dependency>
<groupId>company</groupId>
<artifactId>otherartifact</artifactId>
<version>${my.version}</version>
or
<version>${project.version}</version>
</dependency>
</dependencies>
hth

The correct answer is this (example version):
In parent pom.xml you should have (not inside properties):
<version>0.0.1-SNAPSHOT</version>
In all child modules you should have:
<parent>
<groupId>com.vvirlan</groupId>
<artifactId>grafiti</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
So it is hardcoded.
Now, to update the version you do this:
mvn versions:set -DnewVersion=0.0.2-SNAPSHOT
mvn versions:commit # Necessary to remove the backup file pom.xml
and all your 400 modules will have the parent version updated.

Using a property for the version generates the following warning:
[WARNING]
[WARNING] Some problems were encountered while building the effective model for xxx.yyy.sandbox:Sandbox:war:0.1.0-SNAPSHOT
[WARNING] 'version' contains an expression but should be a constant. # xxx.yyy.sandbox:Sandbox:${my.version}, C:\Users\xxx\development\gwtsandbox\pom.xml, line 8, column 14
[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]
If your problem is that you have to change the version in multiple places because you are switching versions, then the correct thing to do is to use the Maven Release Plugin that will do this for you automatically.

See the Maven - Users forum 'version' contains an expression but should be a constant. Better way to add a new version?:
here is why this is a bad plan.
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.
in maven 2.1.0 and/or 2.2.0 an attempt was made to deploy poms with
resolved properties... this broke more than expected, which is why those
two versions are not recommended, 2.2.1 being the recommended 2.x version.

With a Maven version of 3.5 or higher, you should be able to use a placeholder (e.g. ${revision}) in the parent section and inside the rest of the POM, you can use ${project.version}.
Actually, you can also omit GAV properties outside of <parent> which are the same, as they will be inherited. The result would look something like this:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>build.parent</artifactId>
<groupId>company</groupId>
<version>${revision}</version> <!-- use placeholder -->
<relativePath>../build.parent</relativePath>
</parent>
<artifactId>artifact</artifactId>
<!-- no 'version', no 'groupId'; inherited from parent -->
<packaging>eclipse-plugin</packaging>
...
</project>
For more information, especially on how to resolve the placeholder during publishing, see Maven CI Friendly Versions | Multi Module Setup.

If you're using Maven 3, one option to work around this problem is to use the versions plugin
http://www.mojohaus.org/versions-maven-plugin/
Specifically the commands,
mvn versions:set -DnewVersion=2.0-RELEASE
mvn versions:commit
This will update the parent and child poms to 2.0-RELEASE. You can run this as a build step before.
Unlike the release plugin, it doesn't try to talk to your source control

I have two recommendation for you
Use CI Friendly Revision for all your artifacts. You can add -Drevision=2.0.1 in .mvn/maven.config file. So basically you define your version only at one location.
For all external dependency create a property in parent file. You can use Apache Camel Parent Pom as reference

I have successfully resolved the issue thus:
In parent pom.xml I have sited the version as usual (not inside properties):
<version>0.0.1-SNAPSHOT</version>
In all child modules I used:
<parent>
<groupId>com.example</groupId>
<artifactId>parent-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
Then I changed the parent to:
<version>0.0.2-SNAPSHOT</version>
Now, to update the version I executed in the command line:
mvn -N versions:update-child-modules
The children have been updated automatically to:
<parent>
<groupId>com.example</groupId>
<artifactId>parent-module</artifactId>
<version>0.0.2-SNAPSHOT</version>
</parent>
In other words I have used the versions:update-child-modules goal.
I have found this solution here.

The version of the pom.xml should be valid
<groupId>com.amazonaws.lambda</groupId>
<artifactId>lambda</artifactId>
<version>2.2.4 SNAPSHOT</version>
<packaging>jar</packaging>
This version should not be like 2.2.4. etc

Related

How to make the Maven child project to have different version than the parent?

I am very new to Maven, and I am creating a Maven parent and child project. I want the child project to have a different version than the parent, but if I change the version, then I am getting the error Cannot resolve for some of the dependencies.
How can I have a have a parent version different than the child version?
Following are the current properties I have, which are working pretty fine:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.parent-test</groupId>
<artifactId>io.parent-test</artifactId>
<version>0.9.1-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
<artifactId>test-project-converter</artifactId>
<name>test-project</name>
<description>Test Project</description>
If I change the properties to include the different version for child then I get the error:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.parent-test</groupId>
<artifactId>io.parent-test</artifactId>
<version>0.9.1-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
<version>0.9.2-SNAPSHOT</version>
<artifactId>test-project-converter</artifactId>
<name>test-project</name>
<description>Test Project</description>
I have the following dependencies based on the version that is throwing the error:
<dependency>
<groupId>io.parent-dep</groupId>
<artifactId>parent-dev</artifactId>
<version>${project.version}</version>
</dependency>
I tried to look into some of the responses online and made modifications to my parent project to include the properties:
<properties>
<revision>0.9.2-SNAPSHOT</revision>
</properties>
and accordingly, change the child project to include the version <version>${revision}</version> but it's not working as expected.
Can someone please let me know how can I create a different snapshot version for my child project while keeping the parent project same?
I think because you are building wrong order of child and parent project. When you change the version of child project, you should first re-build child project with new version -> new jar file name (with old parent jar file if in the child project have parent dependency) then update the version of child dependency in the pom file of parent project and re-build parent project, then re-build child project again with the new parent jar file (the same version but include different child jar file).
I was able to fix it by providing the parent version ${project.parent.version} to the dependencies coming from the parent.
I tried this, and everything worked fine.
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.parent-test</groupId>
<artifactId>io.parent-test</artifactId>
<version>0.9.1-SNAPSHOT</version>
<relativePath></relativePath>
</parent>
<version>0.9.2-SNAPSHOT</version>
<artifactId>test-project-converter</artifactId>
<name>test-project</name>
<description>Test Project</description>
<dependencies>
<dependency>
<groupId>io.parent-dep</groupId>
<artifactId>parent-dev</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>

How do I manage version numbers with modularized Maven projects?

I have a fairly typical plugin architecture that looks something like this (just larger):
project
core
data
main
ui
The parent project has a version number defined, is packaged as a pom and defines modules in it's pom.xml:
<groupId>group</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
...
<modules>
<module>core</module>
<module>data</module>
<module>main</module>
<module>ui</module>
</modules>
All of the sub-modules have many references to the parent's version number everywhere. Here is the an example of what the main module looks like to give you an idea:
<parent>
<groupId>group</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>group</groupId>
<artifactId>project.main</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>group</groupId>
<artifactId>group.core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>group</groupId>
<artifactId>group.data</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>group</groupId>
<artifactId>group.ui</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
We're getting tired of having to change the version number over, and over, and over with each release in every parent block, in every artifact block, and in every dependency block for each and every module. On a few occasions, someone used search/replace which hit other files and messed up the build. We tried using properties, but that doesn't work inside the parent definitions for some nonsensical reason.
The version number defined in the parent is the only place we care to manage. We don't even need the sub-modules to even HAVE versions (or artifacts, for that matter). We can do this in our other Ant projects. We can do this in our other Gradle projects. I can't imagine this being impossible in Maven, so I am guessing we are missing something.
How can we define the project's version number in one place, and have that used in all of the parent, artifact, and dependency sections in our modules?
Version maven plugin offers the possibility of changing the subprojects version in one shot. After including the plugin:
mvn versions:set -DnewVersion=<your version>
And if everything is correct:
mvn versions:commit

How to update child pom version using maven and jenkins

I have created a jenkins job where I am passing ReleaseNumber as a parameter, I want this ReleaseNumber to be updated in every pom.xml file (root and child pom), since I am uploading these wars in nexus repository, same version number wont be accepted by nexus.
I want to update child pom version and parent pom version as well.
I am using maven 3.5
I am using this command which I think its not working
mvn org.codehaus.mojo:versions-maven-plugin:2.5:set -DnewVersion-${ReleaseNumber}
This is my parent pom looks like
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.test</groupId>
<artifactId>Wars</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
and this is my child pom looks like
<parent>
<groupId>com.test.test</groupId>
<artifactId>TestWar</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.test.testwar</groupId>
<artifactId>TestWar</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>testWar</name>
Thanks In Advance
Is there a variable ${ReleaseNumber} defined in pom? Or you just copy/pasted it?
You have typo, not - but =
-DnewVersion=${ReleaseNumber}

best practice for making a maven parent project

I developped a multi-module project which is a kind of java web framework.
One of the submodules is a parent pom that I provide for the users of my framework. This parent configures plugins and dependencies for them.
My problem is that this parent pom must refers the sibling modules with their version, which is ${project.version}, and because of the maven project inheritance, the ${project.version} is not the one I want.
To illustrate, my framework projects structure looks like :
my-framework/
|_pom.xml
|_parent/
|_pom.xml
|_server/
|_pom.xml
|_ui/
|_pom.xml
and my parent pom looks like :
<project
....
<!-- General information -->
<modelVersion>4.0.0</modelVersion>
<artifactId>my-framework-parent</artifactId>
<packaging>pom</packaging>
<parent>
<groupId>my.framework</groupId>
<artifactId>my-framework</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<my.framework.version>${project.version}</my.framework.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>my.framework</groupId>
<artifactId>my-framework-server</artifactId>
<version>${my.framework.version}</version>
</dependency>
<dependency>
<groupId>my.framework</groupId>
<artifactId>my-framework-ui</artifactId>
<version>${my.framework.version}</version>
</dependency>
</dependencyManagement>
...
</project>
Then, if a user uses this parent, as maven resolves ${project.version} in the context of the user's project, ${my.framework.version} will be the user's project version instead my framework's version.
To solve this I generated the parent pom I want thanks to the maven-resources-plugin and I overrided the maven-install-plugin behaviour to install the generated pom.
My solution looks tricky and I would like if someone who faced the same problem has a better solution?
I finally found a solution thanks to the flatten-maven-plugin.
But I had to post a pull request to support the pluginManagement section.
https://github.com/mojohaus/flatten-maven-plugin/pull/10
So the solution was to modify my parent pom thanks to this plugin before publishing it. As a result I can set the version I want instead of using ${project.version}.

How to use Maven Release Plugin with Multiple Maven Projects

I'm using Maven 3.
I have multiple maven projects, namely: the 'data model', the 'service', and the 'presentation', split into 3 different projects. They are configured separately (ie. not using maven parent pom).
I have maven release plugin setup on my project correctly, such that when I run mvn release:clean release:prepare release:perform on each individual project, it updates the project version (ie: from 3.4.5-SNAPSHOT to 3.4.5) as well as all the other things.
The problem here is, 'presentation' is dependent on 'service' is dependent on 'data model', and I refer to the projects in the pom files with the version number.
While I develop, say for example I would refer to 'service' in 'presentation' as 3.4.5-SNAPSHOT. But during deploy, I have to release 'service' to change the version to 3.4.5, then I have to update my version reference of 'service' in 'presentation', before I can run a release on 'presentation'.
Is there an automated way of doing this such that I don't need to update the reference of dependent projects during release?
What I have so from thanks to below comments: Updated: 25/03/2013
Run maven with:
versions:use-releases -Dmessage="update from snapshot to release" scm:checkin release:clean release:prepare release:perform
Outcome: version updated, but release build failed.
The Versions Maven Plugin may help you to achieve requirement, especially the goal versions:use-releases. You may be interested in the goal versions:use-next-releases and versions:use-latest-releases as well.
Side Note:
Normally, the good practice is define them as a Maven Multiple Module( here and here). This allow us to manage the version easier as the following example.
The parent
<groupId>my-group</groupId>
<artifactId>my-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
.....
<modules>
<module>my-model</module>
<module>my-service</module>
<module>my-ui</module>
</modules>
The my-model
<parent>
<groupId>my-group</groupId>
<artifactId>my-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>my-model</artifactId>
The my-service
<parent>
<groupId>my-group</groupId>
<artifactId>my-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>my-service</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>my-model</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
The my-ui
<parent>
<groupId>my-group</groupId>
<artifactId>my-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>my-ui</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>my-service</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
Regarding to the above example when we release, the related version will be updated based on the parent version automatically.

Categories