how to handle versions in maven? - maven

I have all these version numbers throughout parent pom and children poms including the parent reference like so
<parent>
<groupId>com.cigna.ifp</groupId>
<artifactId>ifp-core</artifactId>
<version>${parent.version}</version>
</parent>
and dependency references to other child projects like so
<dependency>
<groupId>com.cigna.ifp</groupId>
<artifactId>ifp-shared</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
and finally the declaration of the version of the thing we are building
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>artifcat</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ifp-shared</name>
<url>http://maven.apache.org</url>
EDIT based on some answers which solved half the question...
We want to have all the versions be ${project.version} since it is really just one project with one release number.
I can seem to do ${project.version} in the dependency but this does not work in the parent xml code above. Is there another way? (man, I should really just switch to gradle).
thanks,
Dean

<parent>
<groupId>com.cigna.ifp</groupId>
<artifactId>ifp-core</artifactId>
<version>1.2.3-SNAPSHOT</version> <!-- real version-->
</parent>
<artifactId>blah</artifactId>
<!-- No version here, will be inherited -->
<dependency>
<groupId>com.cigna.ifp</groupId>
<artifactId>ifp-shared</artifactId>
<version>${project.version}</version>
</dependency>

project.version is what you want. Not parent.version.

You need to use dependencyManagement tag to centerilize the versions in the parent pom for the dependencies.
See this question and answers
differences between dependencymanagement and dependencies in maven
For you your own modules, some of the properties are inherited from the parent pom. You will need to declare the parent version in each child but you don't need to declare a groupId/version in your child poms if you want them to be same as their parent's.

We switched to gradle which works fabulously now. Every automated build a new version is released as 1.2.x where x is the next build number. Downstream, projects depend on 1.2.+. This allows every release to be official so QA can test it, reject it or go, yup, build 1.2.568 is the release we will release to the world. Projects can depend on 1.2. but then they don't get bug fixes. This seems to work much better than all that snapshot nonsense as you give QA a snapshot and they approve and you have to change and do another build. We want every build to look official so they can release the one that happens to pass all QA tests.

Related

versions-maven-plugin:update-property not updating pom.xml

Hi Meier I have used the following goal:
mvn versions:update-property
-Dproperty="emom.web.dependency.shr.version"
-Dincludes:org.safeway.com:emom-shr
-DgenerateBackupPoms=false
-DallowIncrementalVersios=true
-DallowSnapshots=true
clean package
My Job B pom.xml is:
<dependency>
<groupId>com.safeway.app</groupId>
<artifactId>emom-shr</artifactId>
<version>${emom.web.dependency.shr.version}</version>
</dependency>
Under the properties it has the version hard-coded:
<emom.web.dependency.shr.version>19.6.5-SNAPSHOT</emom.web.dependency.shr.version>
My Job A pom.xml:
<groupId>com.safeway.app</groupId>
<artifactId>emom-shr</artifactId>
<version>20.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
When I run the above goal, Maven is picking the latest version (i.e. 20.1.0) from Artifactory but when I check the pom.xml of Job B under properties it still says 19.6.5. I need a way to change the 19.6.5 or current version to latest version available. Am I doing something wrong? I'm not able to figure it out.
Here's an example of versions-maven-plugin:update-property working in practice. I've used the common Mockito library as an example that works for everyone as it's in Maven Central.
Starting with this POM (noting the mockito-version property):
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>abc</groupId>
<artifactId>def</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<mockito-version>2.22.0</mockito-version>
</properties>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
The simplest way to upgrade it to the latest release version is this:
mvn versions:update-property -Dproperty=mockito-version
Replace mockito-version with emom.web.dependency.shr.version in your case.
You can then start to use more of the goal options to adjust the options. For example, you might:
Permit snapshots, not just releases, with -DallowSnapshots=true.
Disallow major version updates (i.e. third element from the right) with -DallowMajorUpdates=false. Note that the logic around these version number sections seems a bit flaky in the plugin - or isn't how I expect.
Avoid creating backup POMs with -DgenerateBackupPoms=false. This is cleaner, but if you omit this option then you can use mvn versions:revert to get yourself back to where you started.
To apply this to your scenario, I think you need to:
Check you've not got typos in your actual command (like you have in the question and comments).
Get rid of options that don't appear in the options.
Probably, keep things simple by not trying to run this in conjunction with anything else (unless it's in automation), so get rid of the clean package at the end of the command.

Maven "conditional" parent POM?

What's the best structure for a (multi-module) Maven project which should build "in the wild" without any Maven repository manager and can easily build within my organization where deployments should happen to my Maven repository manager?
Ideally, I would have two different paren POMs for each situation.
But unfortunately, I can't use a Maven property to pass the correct value for each situation, because the property expression in the parent POM reference doesn't get interpolated, if I try something like
<parent>
<groupId>org.example</groupId>
<artifactId>${root.pom}</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/>
</parent>
...
<properties>
<root.pom>wild-parent</root.pom>
</properties>
Added a minimalistic project which shows a crude approach to solve this by patching the parent POM via sed.
This response on the maven-users mailing list pointed me in the direction to use Maven properties to pass in the in-house specifics.
I updated the example project.

How do I default sub-module versions in a Maven multi-module project using snapshots?

I looked at previous questions on the topic and it seems people were a step ahead of where am I at the moment.
I am currently trying to use the maven release plugin to my multi module project. I start from scratch (more exactly, I retrieved some old projects to put in a new multi module project).
I have a POM parent that I defines as:
<groupId>com.somestuff</groupId>
<artifactId>stuff</artifactId>
<version>10.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name> stuff </name>
My child modules inherits the parent using:
<parent>
<groupId>com.somestuff</groupId>
<artifactId>stuff</artifactId>
<version>10.0.0-SNAPSHOT</version>
</parent>
So since it’s a new project, I specify the dependencies between modules as snapshots. For example, if module A depends on module B, I will add to A’s POM the part:
<dependencies>
<dependency>
<groupId>com.somestuff</groupId>
<artifactId>divarmiclient</artifactId>
<version>10.0.0-SNAPSHOT </version>
</dependency>
</dependencies>
The result is when I try to do a “mvn release:prepare”, Maven will yell that there is snapshot dependencies. But since it’s a whole new project, and that versions prior to 10 don’t exist, I have no idea how to default the version values of the modules.
My question is, how shall I default the module values ? How do I do in order to make my multi-module project acceptable from a snapshot perspective ?
For clarification, you're saying your structure is:
theparent
pom.xml
A/
pom.xml
B/
pom.xml
And the following assumptions all hold true:
theparent, A, and B are currently on same version
releases will always be kicked off from 'theparent' level so they remain on same version
A depends on B, always same version
Then the solution is as follows:
<dependency>
<groupId>com.somestuff</groupId>
<artifactId>B</artifactId>
<version>${project.version}</version>
</dependency>

Maven - How/Why/Should it work to set the parent version to be based on a property defined in the parent pom?

I have the following POM structures:
/home/projects/parent/pom.xml
<project>
<groupId>com.my.group</groupId>
<artifactId>project-super-parent</artifactId>
<version>${major.version}.${minor.version}</version>
<packaging>pom</packaging>
<properties>
<major.version>7</major.version>
<minor.version>5</minor.version>
<current.release.version>${major.version}.${minor.version}-SNAPSHOT</current.release.version>
...
</properties>
....
</project>
/home/projects/module1/pom.xml
<project>
<groupId>com.my.group</groupId>
<artifactId>module1</artifactId>
<version>${current.release.version}</version>
<packaging>jar</packaging>
<parent>
<groupId>com.my.group</groupId>
<artifactId>project-super-parent</artifactId>
<version>${major.version}.${minor.version}</version>
<relativePath>../parent</relativePath>
</parent>
...
</project>
Notice that the module does not know the version of it's parent - it uses a property defined in the parent, so this is a kind of a chicken & an egg problem.
The weird thing is - that this works - so when I want to change the major version of the product - I only change a single pom file (the parent).
The limitations to this solution is that I have to have all POM files on the file system.
My questions are: should this even work? How exactly does it work? Is it likely to stop working when I upgrade to maven 3? Is this a commonly used solution or an abuse of the system?
Currently using Maven 2.2.1 and Java 7.
Is this a commonly used solution or an abuse of the system?
That is not common, at least I have never seen it before. The versioning you have in parent/pom.xml and module1/pom.xml will cause a confusion. The parent has a RELEASED version of 7.5, while module1 has a SNAPSHOT version of 7.5. You should not be developing 7.5-SNAPSHOT if 7.5 is already released.
The simplest way to avoid duplication is to maintain the version only in the parent. You can just omit the version declaration in module1. Take a look another project, e.g. maven-3 source code for example. You will be able to see the the version is only declared in the parent pom, and not in any of its child poms.
maven-release-plugin will help you handle the version upgrade and release them for you.
Omitting the version element from the child pom gives error.
Property can be used in Main pom and the same can be inherited by child pom's. When you run the Main pom, build will result in success. Problems are
That you can not build the child pom independently
This does not work in case of transitive dependencies
if you upgrade to Maven 3 in future than it will give error "Non-resolvable parent pom
These problems can be resolved if we are able to update the project pom file as part of the build process before it gets installed in local repository

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