Maven version:set does not update child modules - maven

After finally getting tired of maven release plugin I deceided to move on to something more simpler.
I have a project, with a couple of modules.
When I do
mvn versions:set -DnewVersion=1.0.2-SNAPSHOT
it just changes the parent and skips all child modules?
what am I doing wrong? do I need to set another parameter as well?

I had the same problem of submodules referencing external parents.
If the child's parent version matches the parent's local version, then it updates the versions of the parent and child (it might say SKIPPED but still work, bizarrely). If they don't match then it seems to only update the parent's version and update the children to point to the new parent, it doesn't change the children's versions at all.
Finally i found that wildcards could resolve this problem (requires a new'ish version of the versions plugin):
mvn org.codehaus.mojo:versions-maven-plugin:2.2:set -DnewVersion=1.5.0a -DartifactId=* -DgroupId=*

Alternatively you can also use the processAllModules parameter.
$ mvn versions:set -DnewVersion=2.0.0 -DprocessAllModules

If you're like me with a project whose child modules don't match the parent's version, another option is to adjust them to match first:
$ mvn versions:update-child-modules
then versions:set (and versions:replace-snapshot etc.) will now work as expected, without needing a newer version of the plugin :)
$ mvn versions:set -DnewVersion=1.0.2-SNAPSHOT

I'm assuming that your project structure is like this:
parent/pom.xml
child/pom.xml
Then you have to run mvn versions:set -DnewVersion=1.0.2-SNAPSHOT from parent/ directory.

If anyone searching for an answer, below command worked like a charm for me
mvn release:update-versions -DdevelopmentVersion=4.4.0-SNAPSHOT

Maybe is because you don't declare the plugin in parent pom in Plugin Management. If you want to propagate the plugin to the childs you have to declare in Plugin Management Section.
See: http://maven.apache.org/pom.html#Plugin_Management

I eventually ran mvn -X to discover one of my child poms was saved in UTF-8 BOM encoding:
[DEBUG] Could not parse child-project\pom.xml
java.io.IOException: only whitespace content allowed before start tag and not \uef (position: START_DOCUMENT seen \uef... #1:1)
at org.codehaus.mojo.versions.api.PomHelper.getRawModel (PomHelper.java:116)
The Exception was 'hidden' in DEBUG logging.
I re-saved it using UTF-8 encoding, and it worked.
(Encountered with Maven 3.5.4 / Versions-Maven-Plugin 2.7)

Related

How to update/fix a single child module's parent version

Structure
I know this project structure is not "the Maven way" and this is why I struggle in the first place. Unfortunately I cannot change the project structure.
I try to simplify it as much as possible:
/module-a
/module-b
/module-c
/parent <- <parent>master</parent>, <modules>module-a, module-b, module-c</modules>
/parent/aggregator-d <- <parent>parent</parent>, <modules>module-a, module-b</modules>
/parent/aggregator-t <- <parent>parent</parent>, <modules>module-a</modules>
Use Case
The version of all modules should be changed to a given version. Apart from the parent module, no module explicitly defines its version, so only the parent version has to be changed. But since the parent version is referenced in all other modules, they have to be updated accordingly.
This works fine (using release:update-versions -DautoVersionSubmodules on the parent) for all modules that are listed in a <modules> section in the parent POM (or activated profile).
However, the remaining modules aggregator-d and aggregator-t are not updated.
Failed attempts
So I thought I'd update the remaining modules separately, using mvn --non-recursive, but with no luck so far.
With the release plugin, I only managed to update their own version, using release:update-versions, however this does not update the referenced parent version, so it results in a module version different than the parent version (the explicit module version declaration has been added by the release plugin):
<parent>
[...]
<version>1.0.0-SNAPSHOT</version>
</parent>
<version>1.0.0-changed-SNAPSHOT</version> <- added by release plugin
Using the versions plugin, versions:set fails because the module version is defined by its parent, versions:update-parent does not work because I cannot specify the new parent version (instead the newest version found in the remote repository will be set) and versions:update-child-modules tells me that all child modules are up to date (because the idea is to run it on an aggregator which references the module I want to have updated).
Other ideas
The Maven commands are executed within a Jenkins declarative pipeline, so maybe I could try the (deprecated) writeMavenPom.
Apart from that and using something like sed or maven-antrun-plugin for regex replacement, I've run out of ideas.
Reading more documentation on the versions Maven plugin I noticed that for the parameter newVersion of versions:update-property it says:
If you like to define the version to be used exactly you have to use it like this: -DnewVersion=[19.0] otherwise a newer existing version will be used.
So I applied this information to the parameter parentVersion of versions:update-parent, together with -DallowSnapshots. I then got this warning (while the build still succeeded):
[WARNING] Not updating version: could not resolve any versions
Luckily I found out that the desired version is not required to exist in the remote repository, it's OK if it exists in the local repository. So what I did to finally make everything work is just mvn --non-recursive install the parent POM before using versions:update-parent.
All in all I do this now (-N is --non-recursive, ${v} resolves to e.g. 1.0.0-changed-SNAPSHOT):
mvn -f parent release:update-versions -DautoVersionSubmodules -DdevelopmentVersion=${v}
mvn -f parent -N install
mvn -f parent/aggregator-d -N versions:update-parent -DallowSnapshots -DparentVersion=[${v}]
mvn -f parent/aggregator-t -N versions:update-parent -DallowSnapshots -DparentVersion=[${v}]
This solution is not very pretty but i favor it over using regex or deprecated Jenkins API.

mvn versions:set doesn't update all pom.xml files

We run mvn versions:set -DnewVersion=x.x.x to update the version of our project. For some projects it updates the version in all pom.xml files except one or two. What are some reasons that this command wouldn't update all files?
There are some reasons. The parent is not correctly set in the childs. The childs have different versions as the parent or the other childs. The child is only part of the aggregator based on some profiles.
So you can try with:
mvn version:set -DnewVersion=3.6.0 -DoldVersion=* -DgroupId=* -DartifactId=*
This is explained at https://www.mojohaus.org/versions-maven-plugin/examples/setaggregator.html.
For more advice we would need the pom files.

How to set the parent pom version on a project

I'm using the versions plugin to... set versions.
mvn versions:set -DnewVersion=XXXX
That work's great on aggregate project with declared modules
Now my question is how, in other maven project can I change the parent pom version ? I've placed high hopes in the versions:update-parent but I would like just to set the parent with the version i'm specifying regardless whether that version is deployed or not. Besides I can't get it to work. It never modifies the actual pom. Is there a way to do just that using a mvn plug-in ? Right now it's a manual pom.xml edit.
Thanks
Aa.
I usually use release plugin for that. It changes version of the parent and all the submodules:
mvn release:update-versions -DautoVersionSubmodules=true
Details are here:
http://maven.apache.org/maven-release/maven-release-plugin/examples/update-versions.html

Maven does not take newly built snapshot, uses global repository

I am trying to build a patch branch, into which I build both a parent(a snapshot) and a child(a snapshot as well) as modules listed in an aggregation pom.
Maven finds out everyone depends on the parent, and builds it first, BUT it does not use the newly built parent when I build into clean repository.
When built immediately afterwards, against the same repository, that the built Parent 2.2.5- Snapshot is installed in already, everything works correctly and the patched parent is used in its children.
The problem is that the CI build is always built on a clean repo, and hence, the parent that we use is the one from the global repository, not the local one.
Is this wrong pom.xml, maven settings or possible a bug in maven algorithm?
I tried
mvn clean install -nsu
but in vain.
If you use the option -nsu which means:
-nsu,--no-snapshot-updates Suppress SNAPSHOT updates
It will never use the most up-to-date snapshots. To force maven to do so you should use:
mvn -U clean install
instead.
It turned out the major problem was that we were building the parent pom together with the rest.
Maven downloads all parents first and then resolves dependencies.
So, it was not correct that the parent is listed together with the rest, as a module, when this is a clean build and this version of the parent was not yet deployed(children saw an old snapshot of it instead).
Solution 1: use relativePath to point to the branched parent. This is the better solution in case you do not have very complex hierarchy of modules.
Solution 2: build and deploy the parent of the patch first, so that it is seen by all children, and hence they use correct versions of each other.

Updating the versions in a Maven multi-module project

I have Maven multi-module project and I would like to update the development versions to a given value using a script. The aggregator POM is only an aggregator and the children do not inherit from it. This is important because the artifacts all inherit from other POM files. Here is my structure
aggregator/
--projectA
--projectB
Also, projectB has a Maven dependency on projectA.
First I tried:
mvn -DnewVersion=0.28-SNAPSHOT -DupdateMatchingVersions=true versions:set
It only updated the aggregator project's version.
If I run the Maven release process, it correctly updates projectB's dependency on projectA to use the new development version after the release build. Because the release process handles this well, I thought that using the release plugin might solve my issue.
So I tried the following:
mvn -DdevelopmentVersion=0.28-SNAPSHOT -DautoVersionSubmodules=true --batch-mode release:update-versions
This updated all of my sub-projects correctly. However it did not update projectB's dependency version for projectA.
What is a simple way to update all the development versions in my project, including projectB's dependency on projectA?
You may have more luck with the release plugin but it may require some tweaking
versions:set is designed to update the version of the pom that it executes against... ie the root of the reactor.
If you follow it's conventions, then it will work... But you need to know its conventions.
When you have /project/parent/version and /project/version both specified but "accidentally" at the same value, the versions plugin assumes that the two versions are just accidentally the same, and so does not update the child project's version when the parent version is being updated. updateMatchingVersions tells the plugin to assume that it us not an accident and that the child should be in lock step.
If you only specify /project/parent/version and leave the project version unspecified, therefore relying on inheritance, the plugin will add the child project to the list of version changes (and hence loop through all the projects again to ensure it catches any additional required changes)
The versions plugin does not currently provide an option to force everything to the one version... Though that might be a good idea.
You can get what you want with three commands, eg
mvn versions:set -DnewVersion=...
cd projectA
mvn versions:set -DnewVersion=...
cd ../projectB
mvn versions:set -DnewVersion=...
This is because versions:set will attempt to "grow" the reactor if the parent directory contains an aggregator pom that references the invoked project...
In other words when you have a reactor with no common parent, versions assumes that the common version number is by accident, but it will pick up the intent from the wider reactor
# for each module into aggregator pom
for module in $(grep "\<module\>" pom.xml | sed 's/<\/module>//g' | sed 's/.*<module>//g' | sed 's/.*\///g')
do
# set the version of the module
# and update reference to this module into others modules
mvn versions:set -DgenerateBackupPoms=false -DartifactId=$module \
-DnewVersion=$newVersion -DupdateMatchingVersions=true
done
# set the version of the aggregator pom
mvn versions:set versions:commit -DnewVersion=$newVersion
i found your same problem ,then i clone versions plugin code , then I found if you set gropuId,artifcatId,oldVersion value tobe * will solve the problem;
like this :
mvn versions:set -DnewVersion=xxx -DgroupId=* -DartifactId=* -DoldVersion=*

Resources