How to automate version number update process for my Eclipse plugin built with Maven - maven

I working with a project similar to the project described here.
So, it has a few modules in parent pom.xml:
<modules>
<module>../de.vogella.tycho.plugin</module>
<module>../de.vogella.tycho.feature</module>
<module>../de.vogella.tycho.p2updatesite</module>
</modules>
These modules have a general version number e.g. 1.0.0-SNAPSHOT or without -SNAPSHOT. The feature.xml file needs to contain the same version number:
<feature
id="com.my.feature"
label="My plugin feature"
version="1.0.0">
and:
<plugin
id="com.my.plugin"
download-size="0"
install-size="0"
version="1.0.0"
unpack="false"/>
The files category.xml (in p2 update-site projects) and MANIFEST.MF (in plugin projects) need to contain the same value.
The question is: How to automate the version number update process in all these files using Maven?
I tried to resolve this problem using maven-release-plugin and maven-versions-plugin. The first plugin makes a lot of unused actions (like making a lot of CVS commits, which I do not use in this project). The second plugin only makes changes in pom.xml files and do not modify feature.xml, category.xml and MANIFEST.MF, or I used it not so good.

There is a special tycho-versions-plugin for exactly this problem. It (intentionally) does the same as the maven-versions-plugin, but also updates the (redundant) versions in feature.xml and MANIFEST.MF.
Even more, the plugin also updates references which specify an exact version, like references to plug-ins in a feature.xml, or references to features in a category.xml. So in the end, all occurrences of the artifact versions are updated, like in a refactoring.
For references with exact versions, there is also an automatic update during the normal Tycho build. So if e.g. your feature references your plug-in in version 1.0.0.qualifier, this version string is updated with the actual value of the qualifier, e.g. 1.0.0.201207171147. You can make use of this functionality to minimize the number of places that need to be updated by the tycho-versions-plugin: Instead of specifying the current version literal in the reference, you can use the magic version 0.0.0. This version is also automatically updated to the latest version as part of the normal build.

I'd like to add some practical hints for less experienced maven users like me to Tobias Oberlies' answer:
The goal tycho-versions:set-version will change the version of all projects that are referenced from the master pom. The version strings of the maven configuration files (pom.xml) as well as the respective Eclipse/OSGi artifacts (MANIFEST.MF, feature.xml, category.xml) will be changed consistently.
To run the goal from the command line, use the following:
mvn org.eclipse.tycho:tycho-versions-plugin:set-version -DnewVersion=1.2.0-SNAPSHOT
The newVersion user property, 1.2.0-SNAPSHOT in this example, is the new version to be set.
The above command line will use the latest version of the tycho-versions-plugin. If a certain version of the plugin should be used, the tycho-version-plugin needs to be added to the project/build/plugins element of the master pom.
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-versions-plugin</artifactId>
<version>${tycho-version}</version>
</plugin>
Replace ${tycho-version} with the current version of Tycho or define a property with that name and the appropriate value.

Related

What does <version>RELEASE</version> mean? [duplicate]

In Maven, dependencies are usually set up like this:
<dependency>
<groupId>wonderful-inc</groupId>
<artifactId>dream-library</artifactId>
<version>1.2.3</version>
</dependency>
Now, if you are working with libraries that have frequent releases, constantly updating the <version> tag can be somewhat annoying. Is there any way to tell Maven to always use the latest available version (from the repository)?
NOTE:
The mentioned LATEST and RELEASE metaversions have been dropped for plugin dependencies in Maven 3 "for the sake of reproducible builds", over 6 years ago.
(They still work perfectly fine for regular dependencies.)
For plugin dependencies please refer to this Maven 3 compliant solution.
If you always want to use the newest version, Maven has two keywords you can use as an alternative to version ranges. You should use these options with care as you are no longer in control of the plugins/dependencies you are using.
When you depend on a plugin or a dependency, you can use the a version value of LATEST or RELEASE. LATEST refers to the latest released or snapshot version of a particular artifact, the most recently deployed artifact in a particular repository. RELEASE refers to the last non-snapshot release in the repository. In general, it is not a best practice to design software which depends on a non-specific version of an artifact. If you are developing software, you might want to use RELEASE or LATEST as a convenience so that you don't have to update version numbers when a new release of a third-party library is released. When you release software, you should always make sure that your project depends on specific versions to reduce the chances of your build or your project being affected by a software release not under your control. Use LATEST and RELEASE with caution, if at all.
See the POM Syntax section of the Maven book for more details. Or see this doc on Dependency Version Ranges, where:
A square bracket ( [ & ] ) means "closed" (inclusive).
A parenthesis ( ( & ) ) means "open" (exclusive).
Here's an example illustrating the various options. In the Maven repository, com.foo:my-foo has the following metadata:
<?xml version="1.0" encoding="UTF-8"?><metadata>
<groupId>com.foo</groupId>
<artifactId>my-foo</artifactId>
<version>2.0.0</version>
<versioning>
<release>1.1.1</release>
<versions>
<version>1.0</version>
<version>1.0.1</version>
<version>1.1</version>
<version>1.1.1</version>
<version>2.0.0</version>
</versions>
<lastUpdated>20090722140000</lastUpdated>
</versioning>
</metadata>
If a dependency on that artifact is required, you have the following options (other version ranges can be specified of course, just showing the relevant ones here):
Declare an exact version (will always resolve to 1.0.1):
<version>[1.0.1]</version>
Declare an explicit version (will always resolve to 1.0.1 unless a collision occurs, when Maven will select a matching version):
<version>1.0.1</version>
Declare a version range for all 1.x (will currently resolve to 1.1.1):
<version>[1.0.0,2.0.0)</version>
Declare an open-ended version range (will resolve to 2.0.0):
<version>[1.0.0,)</version>
Declare the version as LATEST (will resolve to 2.0.0) (removed from maven 3.x)
<version>LATEST</version>
Declare the version as RELEASE (will resolve to 1.1.1) (removed from maven 3.x):
<version>RELEASE</version>
Note that by default your own deployments will update the "latest" entry in the Maven metadata, but to update the "release" entry, you need to activate the "release-profile" from the Maven super POM. You can do this with either "-Prelease-profile" or "-DperformRelease=true"
It's worth emphasising that any approach that allows Maven to pick the dependency versions (LATEST, RELEASE, and version ranges) can leave you open to build time issues, as later versions can have different behaviour (for example the dependency plugin has previously switched a default value from true to false, with confusing results).
It is therefore generally a good idea to define exact versions in releases. As Tim's answer points out, the maven-versions-plugin is a handy tool for updating dependency versions, particularly the versions:use-latest-versions and versions:use-latest-releases goals.
Now I know this topic is old, but reading the question and the OP supplied answer it seems the Maven Versions Plugin might have actually been a better answer to his question:
In particular the following goals could be of use:
versions:use-latest-versions searches the pom for all versions
which have been a newer version and
replaces them with the latest
version.
versions:use-latest-releases searches the pom for all non-SNAPSHOT
versions which have been a newer
release and replaces them with the
latest release version.
versions:update-properties updates properties defined in a
project so that they correspond to
the latest available version of
specific dependencies. This can be
useful if a suite of dependencies
must all be locked to one version.
The following other goals are also provided:
versions:display-dependency-updates scans a project's dependencies and
produces a report of those
dependencies which have newer
versions available.
versions:display-plugin-updates scans a project's plugins and
produces a report of those plugins
which have newer versions available.
versions:update-parent updates the parent section of a project so
that it references the newest
available version. For example, if
you use a corporate root POM, this
goal can be helpful if you need to
ensure you are using the latest
version of the corporate root POM.
versions:update-child-modules updates the parent section of the
child modules of a project so the
version matches the version of the
current project. For example, if you
have an aggregator pom that is also
the parent for the projects that it
aggregates and the children and
parent versions get out of sync, this
mojo can help fix the versions of the
child modules. (Note you may need to
invoke Maven with the -N option in
order to run this goal if your
project is broken so badly that it
cannot build because of the version
mis-match).
versions:lock-snapshots searches the pom for all -SNAPSHOT
versions and replaces them with the
current timestamp version of that
-SNAPSHOT, e.g. -20090327.172306-4
versions:unlock-snapshots searches the pom for all timestamp
locked snapshot versions and replaces
them with -SNAPSHOT.
versions:resolve-ranges finds dependencies using version ranges and
resolves the range to the specific
version being used.
versions:use-releases searches the pom for all -SNAPSHOT versions
which have been released and replaces
them with the corresponding release
version.
versions:use-next-releases searches the pom for all non-SNAPSHOT
versions which have been a newer
release and replaces them with the
next release version.
versions:use-next-versions searches the pom for all versions
which have been a newer version and
replaces them with the next version.
versions:commit removes the pom.xml.versionsBackup files. Forms
one half of the built-in "Poor Man's
SCM".
versions:revert restores the pom.xml files from the
pom.xml.versionsBackup files. Forms
one half of the built-in "Poor Man's
SCM".
Just thought I'd include it for any future reference.
Please take a look at this page (section "Dependency Version Ranges"). What you might want to do is something like
<version>[1.2.3,)</version>
These version ranges are implemented in Maven2.
Unlike others I think there are many reasons why you might always want the latest version. Particularly if you are doing continuous deployment (we sometimes have like 5 releases in a day) and don't want to do a multi-module project.
What I do is make Hudson/Jenkins do the following for every build:
mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true
That is I use the versions plugin and scm plugin to update the dependencies and then check it in to source control. Yes I let my CI do SCM checkins (which you have to do anyway for the maven release plugin).
You'll want to setup the versions plugin to only update what you want:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<includesList>com.snaphop</includesList>
<generateBackupPoms>false</generateBackupPoms>
<allowSnapshots>true</allowSnapshots>
</configuration>
</plugin>
I use the release plugin to do the release which takes care of -SNAPSHOT and validates that there is a release version of -SNAPSHOT (which is important).
If you do what I do you will get the latest version for all snapshot builds and the latest release version for release builds. Your builds will also be reproducible.
Update
I noticed some comments asking some specifics of this workflow. I will say we don't use this method anymore and the big reason why is the maven versions plugin is buggy and in general is inherently flawed.
It is flawed because to run the versions plugin to adjust versions all the existing versions need to exist for the pom to run correctly. That is the versions plugin cannot update to the latest version of anything if it can't find the version referenced in the pom. This is actually rather annoying as we often cleanup old versions for disk space reasons.
Really you need a separate tool from maven to adjust the versions (so you don't depend on the pom file to run correctly). I have written such a tool in the the lowly language that is Bash. The script will update the versions like the version plugin and check the pom back into source control. It also runs like 100x faster than the mvn versions plugin. Unfortunately it isn't written in a manner for public usage but if people are interested I could make it so and put it in a gist or github.
Going back to workflow as some comments asked about that this is what we do:
We have 20 or so projects in their own repositories with their own jenkins jobs
When we release the maven release plugin is used. The workflow of that is covered in the plugin's documentation. The maven release plugin sort of sucks (and I'm being kind) but it does work. One day we plan on replacing this method with something more optimal.
When one of the projects gets released jenkins then runs a special job we will call the update all versions job (how jenkins knows its a release is a complicated manner in part because the maven jenkins release plugin is pretty crappy as well).
The update all versions job knows about all the 20 projects. It is actually an aggregator pom to be specific with all the projects in the modules section in dependency order. Jenkins runs our magic groovy/bash foo that will pull all the projects update the versions to the latest and then checkin the poms (again done in dependency order based on the modules section).
For each project if the pom has changed (because of a version change in some dependency) it is checked in and then we immediately ping jenkins to run the corresponding job for that project (this is to preserve build dependency order otherwise you are at the mercy of the SCM Poll scheduler).
At this point I'm of the opinion it is a good thing to have the release and auto version a separate tool from your general build anyway.
Now you might think maven sort of sucks because of the problems listed above but this actually would be fairly difficult with a build tool that does not have a declarative easy to parse extendable syntax (aka XML).
In fact we add custom XML attributes through namespaces to help hint bash/groovy scripts (e.g. don't update this version).
The dependencies syntax is located at the Dependency Version Requirement Specification documentation. Here it is is for completeness:
Dependencies' version element define version requirements, used to compute effective dependency version. Version requirements have the following syntax:
1.0: "Soft" requirement on 1.0 (just a recommendation, if it matches all other ranges for the dependency)
[1.0]: "Hard" requirement on 1.0
(,1.0]: x <= 1.0
[1.2,1.3]: 1.2 <= x <= 1.3
[1.0,2.0): 1.0 <= x < 2.0
[1.5,): x >= 1.5
(,1.0],[1.2,): x <= 1.0 or x >= 1.2; multiple sets are comma-separated
(,1.1),(1.1,): this excludes 1.1 (for example if it is known not to
work in combination with this library)
In your case, you could do something like <version>[1.2.3,)</version>
Are you possibly depending on development versions that obviously change a lot during development?
Instead of incrementing the version of development releases, you could just use a snapshot version that you overwrite when necessary, which means you wouldn't have to change the version tag on every minor change. Something like 1.0-SNAPSHOT...
But maybe you are trying to achieve something else ;)
Who ever is using LATEST, please make sure you have -U otherwise the latest snapshot won't be pulled.
mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST
// pull the latest snapshot for my-foo from all repositories
The truth is even in 3.x it still works, surprisingly the projects builds and deploys. But the LATEST/RELEASE keyword causing problems in m2e and eclipse all over the place, ALSO projects depends on the dependency which deployed through the LATEST/RELEASE fail to recognize the version.
It will also causing problem if you are try to define the version as property, and reference it else where.
So the conclusion is use the versions-maven-plugin if you can.
By the time this question was posed there were some kinks with version ranges in maven, but these have been resolved in newer versions of maven.
This article captures very well how version ranges work and best practices to better understand how maven understands versions: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855
Sometimes you don't want to use version ranges, because it seems that they are "slow" to resolve your dependencies, especially when there is continuous delivery in place and there are tons of versions - mainly during heavy development.
One workaround would be to use the versions-maven-plugin. For example, you can declare a property:
<properties>
<myname.version>1.1.1</myname.version>
</properties>
and add the versions-maven-plugin to your pom file:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.3</version>
<configuration>
<properties>
<property>
<name>myname.version</name>
<dependencies>
<dependency>
<groupId>group-id</groupId>
<artifactId>artifact-id</artifactId>
<version>latest</version>
</dependency>
</dependencies>
</property>
</properties>
</configuration>
</plugin>
</plugins>
</build>
Then, in order to update the dependency, you have to execute the goals:
mvn versions:update-properties validate
If there is a version newer than 1.1.1, it will tell you:
[INFO] Updated ${myname.version} from 1.1.1 to 1.3.2
If you want Maven should use the latest version of a dependency, then you can use Versions Maven Plugin and how to use this plugin, Tim has already given a good answer, follow his answer.
But as a developer, I will not recommend this type of practices. WHY?
answer to why is already given by Pascal Thivent in the comment of the question
I really don't recommend this practice (nor using version ranges) for
the sake of build reproducibility. A build that starts to suddenly
fail for an unknown reason is way more annoying than updating manually
a version number.
I will recommend this type of practice:
<properties>
<spring.version>3.1.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
it is easy to maintain and easy to debug. You can update your POM in no time.
MY solution in maven 3.5.4 ,use nexus, in eclipse:
<dependency>
<groupId>yilin.sheng</groupId>
<artifactId>webspherecore</artifactId>
<version>LATEST</version>
</dependency>
then in eclipse: atl + F5, and choose the force update of snapshots/release
it works for me.

Maven 3 + RELEASE version in dependency. Valid? [duplicate]

In Maven, dependencies are usually set up like this:
<dependency>
<groupId>wonderful-inc</groupId>
<artifactId>dream-library</artifactId>
<version>1.2.3</version>
</dependency>
Now, if you are working with libraries that have frequent releases, constantly updating the <version> tag can be somewhat annoying. Is there any way to tell Maven to always use the latest available version (from the repository)?
NOTE:
The mentioned LATEST and RELEASE metaversions have been dropped for plugin dependencies in Maven 3 "for the sake of reproducible builds", over 6 years ago.
(They still work perfectly fine for regular dependencies.)
For plugin dependencies please refer to this Maven 3 compliant solution.
If you always want to use the newest version, Maven has two keywords you can use as an alternative to version ranges. You should use these options with care as you are no longer in control of the plugins/dependencies you are using.
When you depend on a plugin or a dependency, you can use the a version value of LATEST or RELEASE. LATEST refers to the latest released or snapshot version of a particular artifact, the most recently deployed artifact in a particular repository. RELEASE refers to the last non-snapshot release in the repository. In general, it is not a best practice to design software which depends on a non-specific version of an artifact. If you are developing software, you might want to use RELEASE or LATEST as a convenience so that you don't have to update version numbers when a new release of a third-party library is released. When you release software, you should always make sure that your project depends on specific versions to reduce the chances of your build or your project being affected by a software release not under your control. Use LATEST and RELEASE with caution, if at all.
See the POM Syntax section of the Maven book for more details. Or see this doc on Dependency Version Ranges, where:
A square bracket ( [ & ] ) means "closed" (inclusive).
A parenthesis ( ( & ) ) means "open" (exclusive).
Here's an example illustrating the various options. In the Maven repository, com.foo:my-foo has the following metadata:
<?xml version="1.0" encoding="UTF-8"?><metadata>
<groupId>com.foo</groupId>
<artifactId>my-foo</artifactId>
<version>2.0.0</version>
<versioning>
<release>1.1.1</release>
<versions>
<version>1.0</version>
<version>1.0.1</version>
<version>1.1</version>
<version>1.1.1</version>
<version>2.0.0</version>
</versions>
<lastUpdated>20090722140000</lastUpdated>
</versioning>
</metadata>
If a dependency on that artifact is required, you have the following options (other version ranges can be specified of course, just showing the relevant ones here):
Declare an exact version (will always resolve to 1.0.1):
<version>[1.0.1]</version>
Declare an explicit version (will always resolve to 1.0.1 unless a collision occurs, when Maven will select a matching version):
<version>1.0.1</version>
Declare a version range for all 1.x (will currently resolve to 1.1.1):
<version>[1.0.0,2.0.0)</version>
Declare an open-ended version range (will resolve to 2.0.0):
<version>[1.0.0,)</version>
Declare the version as LATEST (will resolve to 2.0.0) (removed from maven 3.x)
<version>LATEST</version>
Declare the version as RELEASE (will resolve to 1.1.1) (removed from maven 3.x):
<version>RELEASE</version>
Note that by default your own deployments will update the "latest" entry in the Maven metadata, but to update the "release" entry, you need to activate the "release-profile" from the Maven super POM. You can do this with either "-Prelease-profile" or "-DperformRelease=true"
It's worth emphasising that any approach that allows Maven to pick the dependency versions (LATEST, RELEASE, and version ranges) can leave you open to build time issues, as later versions can have different behaviour (for example the dependency plugin has previously switched a default value from true to false, with confusing results).
It is therefore generally a good idea to define exact versions in releases. As Tim's answer points out, the maven-versions-plugin is a handy tool for updating dependency versions, particularly the versions:use-latest-versions and versions:use-latest-releases goals.
Now I know this topic is old, but reading the question and the OP supplied answer it seems the Maven Versions Plugin might have actually been a better answer to his question:
In particular the following goals could be of use:
versions:use-latest-versions searches the pom for all versions
which have been a newer version and
replaces them with the latest
version.
versions:use-latest-releases searches the pom for all non-SNAPSHOT
versions which have been a newer
release and replaces them with the
latest release version.
versions:update-properties updates properties defined in a
project so that they correspond to
the latest available version of
specific dependencies. This can be
useful if a suite of dependencies
must all be locked to one version.
The following other goals are also provided:
versions:display-dependency-updates scans a project's dependencies and
produces a report of those
dependencies which have newer
versions available.
versions:display-plugin-updates scans a project's plugins and
produces a report of those plugins
which have newer versions available.
versions:update-parent updates the parent section of a project so
that it references the newest
available version. For example, if
you use a corporate root POM, this
goal can be helpful if you need to
ensure you are using the latest
version of the corporate root POM.
versions:update-child-modules updates the parent section of the
child modules of a project so the
version matches the version of the
current project. For example, if you
have an aggregator pom that is also
the parent for the projects that it
aggregates and the children and
parent versions get out of sync, this
mojo can help fix the versions of the
child modules. (Note you may need to
invoke Maven with the -N option in
order to run this goal if your
project is broken so badly that it
cannot build because of the version
mis-match).
versions:lock-snapshots searches the pom for all -SNAPSHOT
versions and replaces them with the
current timestamp version of that
-SNAPSHOT, e.g. -20090327.172306-4
versions:unlock-snapshots searches the pom for all timestamp
locked snapshot versions and replaces
them with -SNAPSHOT.
versions:resolve-ranges finds dependencies using version ranges and
resolves the range to the specific
version being used.
versions:use-releases searches the pom for all -SNAPSHOT versions
which have been released and replaces
them with the corresponding release
version.
versions:use-next-releases searches the pom for all non-SNAPSHOT
versions which have been a newer
release and replaces them with the
next release version.
versions:use-next-versions searches the pom for all versions
which have been a newer version and
replaces them with the next version.
versions:commit removes the pom.xml.versionsBackup files. Forms
one half of the built-in "Poor Man's
SCM".
versions:revert restores the pom.xml files from the
pom.xml.versionsBackup files. Forms
one half of the built-in "Poor Man's
SCM".
Just thought I'd include it for any future reference.
Please take a look at this page (section "Dependency Version Ranges"). What you might want to do is something like
<version>[1.2.3,)</version>
These version ranges are implemented in Maven2.
Unlike others I think there are many reasons why you might always want the latest version. Particularly if you are doing continuous deployment (we sometimes have like 5 releases in a day) and don't want to do a multi-module project.
What I do is make Hudson/Jenkins do the following for every build:
mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true
That is I use the versions plugin and scm plugin to update the dependencies and then check it in to source control. Yes I let my CI do SCM checkins (which you have to do anyway for the maven release plugin).
You'll want to setup the versions plugin to only update what you want:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<includesList>com.snaphop</includesList>
<generateBackupPoms>false</generateBackupPoms>
<allowSnapshots>true</allowSnapshots>
</configuration>
</plugin>
I use the release plugin to do the release which takes care of -SNAPSHOT and validates that there is a release version of -SNAPSHOT (which is important).
If you do what I do you will get the latest version for all snapshot builds and the latest release version for release builds. Your builds will also be reproducible.
Update
I noticed some comments asking some specifics of this workflow. I will say we don't use this method anymore and the big reason why is the maven versions plugin is buggy and in general is inherently flawed.
It is flawed because to run the versions plugin to adjust versions all the existing versions need to exist for the pom to run correctly. That is the versions plugin cannot update to the latest version of anything if it can't find the version referenced in the pom. This is actually rather annoying as we often cleanup old versions for disk space reasons.
Really you need a separate tool from maven to adjust the versions (so you don't depend on the pom file to run correctly). I have written such a tool in the the lowly language that is Bash. The script will update the versions like the version plugin and check the pom back into source control. It also runs like 100x faster than the mvn versions plugin. Unfortunately it isn't written in a manner for public usage but if people are interested I could make it so and put it in a gist or github.
Going back to workflow as some comments asked about that this is what we do:
We have 20 or so projects in their own repositories with their own jenkins jobs
When we release the maven release plugin is used. The workflow of that is covered in the plugin's documentation. The maven release plugin sort of sucks (and I'm being kind) but it does work. One day we plan on replacing this method with something more optimal.
When one of the projects gets released jenkins then runs a special job we will call the update all versions job (how jenkins knows its a release is a complicated manner in part because the maven jenkins release plugin is pretty crappy as well).
The update all versions job knows about all the 20 projects. It is actually an aggregator pom to be specific with all the projects in the modules section in dependency order. Jenkins runs our magic groovy/bash foo that will pull all the projects update the versions to the latest and then checkin the poms (again done in dependency order based on the modules section).
For each project if the pom has changed (because of a version change in some dependency) it is checked in and then we immediately ping jenkins to run the corresponding job for that project (this is to preserve build dependency order otherwise you are at the mercy of the SCM Poll scheduler).
At this point I'm of the opinion it is a good thing to have the release and auto version a separate tool from your general build anyway.
Now you might think maven sort of sucks because of the problems listed above but this actually would be fairly difficult with a build tool that does not have a declarative easy to parse extendable syntax (aka XML).
In fact we add custom XML attributes through namespaces to help hint bash/groovy scripts (e.g. don't update this version).
The dependencies syntax is located at the Dependency Version Requirement Specification documentation. Here it is is for completeness:
Dependencies' version element define version requirements, used to compute effective dependency version. Version requirements have the following syntax:
1.0: "Soft" requirement on 1.0 (just a recommendation, if it matches all other ranges for the dependency)
[1.0]: "Hard" requirement on 1.0
(,1.0]: x <= 1.0
[1.2,1.3]: 1.2 <= x <= 1.3
[1.0,2.0): 1.0 <= x < 2.0
[1.5,): x >= 1.5
(,1.0],[1.2,): x <= 1.0 or x >= 1.2; multiple sets are comma-separated
(,1.1),(1.1,): this excludes 1.1 (for example if it is known not to
work in combination with this library)
In your case, you could do something like <version>[1.2.3,)</version>
Are you possibly depending on development versions that obviously change a lot during development?
Instead of incrementing the version of development releases, you could just use a snapshot version that you overwrite when necessary, which means you wouldn't have to change the version tag on every minor change. Something like 1.0-SNAPSHOT...
But maybe you are trying to achieve something else ;)
Who ever is using LATEST, please make sure you have -U otherwise the latest snapshot won't be pulled.
mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST
// pull the latest snapshot for my-foo from all repositories
The truth is even in 3.x it still works, surprisingly the projects builds and deploys. But the LATEST/RELEASE keyword causing problems in m2e and eclipse all over the place, ALSO projects depends on the dependency which deployed through the LATEST/RELEASE fail to recognize the version.
It will also causing problem if you are try to define the version as property, and reference it else where.
So the conclusion is use the versions-maven-plugin if you can.
By the time this question was posed there were some kinks with version ranges in maven, but these have been resolved in newer versions of maven.
This article captures very well how version ranges work and best practices to better understand how maven understands versions: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855
Sometimes you don't want to use version ranges, because it seems that they are "slow" to resolve your dependencies, especially when there is continuous delivery in place and there are tons of versions - mainly during heavy development.
One workaround would be to use the versions-maven-plugin. For example, you can declare a property:
<properties>
<myname.version>1.1.1</myname.version>
</properties>
and add the versions-maven-plugin to your pom file:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.3</version>
<configuration>
<properties>
<property>
<name>myname.version</name>
<dependencies>
<dependency>
<groupId>group-id</groupId>
<artifactId>artifact-id</artifactId>
<version>latest</version>
</dependency>
</dependencies>
</property>
</properties>
</configuration>
</plugin>
</plugins>
</build>
Then, in order to update the dependency, you have to execute the goals:
mvn versions:update-properties validate
If there is a version newer than 1.1.1, it will tell you:
[INFO] Updated ${myname.version} from 1.1.1 to 1.3.2
If you want Maven should use the latest version of a dependency, then you can use Versions Maven Plugin and how to use this plugin, Tim has already given a good answer, follow his answer.
But as a developer, I will not recommend this type of practices. WHY?
answer to why is already given by Pascal Thivent in the comment of the question
I really don't recommend this practice (nor using version ranges) for
the sake of build reproducibility. A build that starts to suddenly
fail for an unknown reason is way more annoying than updating manually
a version number.
I will recommend this type of practice:
<properties>
<spring.version>3.1.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
it is easy to maintain and easy to debug. You can update your POM in no time.
MY solution in maven 3.5.4 ,use nexus, in eclipse:
<dependency>
<groupId>yilin.sheng</groupId>
<artifactId>webspherecore</artifactId>
<version>LATEST</version>
</dependency>
then in eclipse: atl + F5, and choose the force update of snapshots/release
it works for me.

Custom pom.xml filename in Maven multimodule for Tycho

I have a project with a couple of dozen Eclipse plugins, all inter-related and living in different subfolders. The build was converted to a multi-module manifest-first Tycho build a couple of years ago and it works quite well.
One of the plugins is rather key, and can also be built as a standalone Java app, which doesn't use an Eclipse runtime. Currently it has its own POM file (pom-standalone.xml) so that Jenkins can build the standalone app separately and the Tycho build knows nothing about it - the pom-standalone just lists the previously-built plugin jars (thanks Tycho!) and Eclipse libraries that it needs as dependencies. Couple problems with this approach though:
I cannot easily use IntelliJ to work on the standalone project with Maven dependency management, because it doesn't recognize the custom pom-standalone.xml filename as a POM.
The many jars that this project relies on are checked in to the project for the sake of Tycho and the Eclipse Manifest file, but they're also managed by Maven for the standalone build. So any dependencies have to be added to the pom-standalone.xml file AND entered into the OSGi manifest AND checked in to the source control for Eclipse purposes.
It seems like a straightforward workaround would be to tell Tycho/modules to use something other than pom.xml for the submodule's POM, or perhaps all the multimodule POM files, since Eclipse doesn't use those anyway - then the pom-standalone.xml can be converted to pom.xml and then IntelliJ will be fine with it.
I know you can specify the -f attribute to Maven builds, but will that really apply to all submodules? Can you specify the POM filename for just ONE submodule?
Are there alternative solutions? Eclipse/Tycho/p2 builds seem somewhat of a headache requiring manual library management and checking in libraries to source control, but maybe there have been changes I'm not aware of in the Eclipse build world the last few years.
Found a Similar Question that didn't help much.
You can include projects in an aggregator POM by specifying the full name to the POM file with custom name. Example:
<modules>
<module>org.example.bundle1</module>
<module>org.example.bundle2</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
This both works in a pure Maven and Maven/Tycho build.
To extend #oberlies answer a little bit:
SCENARIO: top aggregation POM comes in multiple flavors, so any style can be built from the top.
<!-- in file pom.xml -->
<modules>
<module>org.example.bundle1</module>
<module>org.example.bundle2</module>
<module>org.example.keybundle</module>
</modules>
All submodules will be built using their standard pom.xml
and
<!-- in file pom-tycho.xml -->
<modules>
<module>org.example.bundle1/pom.xml</module>
<module>org.example.bundle2/pom.xml</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
Submodules will be built using the specifically named POM file.
and, likewise:
<!-- in file pom-special.xml -->
<modules>
<module>org.example.bundle1/pom.xml</module>
<module>org.example.bundle2/pom-special.xml</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
Submodules that have custom POM files use them, and others state they still want the normal POM file, all independent of the name of the top aggregation POM file.
Because mvn -f pom-tycho.xml assumes that file name in all submodules. So if you do want pom.xml in any submodule when the top file isn't named pom.xml you need to fully specify for each submodule.

How to ignore a Maven plugin

We have a groupId for Maven plugins:
com.company.maven.plugins
Unfortunately, when I created the first plugin in this groupId, I initially used the wrong naming convention.
maven-myplugin-plugin
The 1.x versions of the plugin used that name. When I realized this was wrong I changed the name to meet the correct convention.
myplugin-maven-plugin
Then I updated the version to 2.x.
In my local settings.xml file I use the pluginGroups to access my plugins from the command line. This particular plugin does not have to be specified in the pom file.
Unfortunately, when I try to access my plugin from the command line without scoping the name I always get the latest version of the incorrect naming convention. So, I get a 1.x version.
Can I tell Maven to ignore the maven-myplugin-plugin artifacts when accessing from the command line (i.e. mvn myplugin:mygoal)?
Some projects still use the old 1.x plugins, so I don't want to delete them from our repository. Also, we are using at least Maven 3.0.3.
It somehow seems that Maven3 resolves the prefixes from plugins in the order of
1. maven-myplugin-plugin
2. myplugin-maven-plugin
3. ... hard-wired groups ...
Following the official naming convention it should be the other way round imho. Nevertheless, I think you do not have a chance to get this fixed. I tried a set of things, basically playing around with the goalPrefix in the maven-plugin-plugin config. Installing a new version of the deprecated-named plugin with goalPrefix did not work. I guess one thing you could do is defining another prefix for your correctly-named plugin, e.g.:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
<goalPrefix>myplugin2</goalPrefix>
</configuration>
</plugin>
Another approach could be to adjust the old plugin's pom.xml, renaming it to something different. But this would imply that your colleagues would need a different execute a different mvn command. Or you can rename your current plugin - similar results.
If there is a better solution, I would also be interested!

Automatically replacing one Maven plugin with another in a POM

Please do you know if it's possible to automatically replace one Maven plugin with another in the POM files for a project?
The context is that I'm trying to intercept a Scala build using a Scala compiler plugin, for which I want to be able to specify the Scala compiler plugin as an argument to scalac from the command-line (i.e. not within the POM files). This is possible using the latest version of the Scala Maven plugin (known as scala-maven-plugin) by using its addScalacArgs flag - see here: http://davidb.github.com/scala-maven-plugin/apidocs/scala_maven/ScalaMojoSupport.html. However, it's not possible for the old version of the plugin (known as maven-scala-plugin), and I'd need to add the argument in all the various POM files (not an attractive proposition when dealing with a large, third-party project).
My thinking is that if I can automatically replace the old version of the plugin with the new version in the POM files, then I can use addScalacArgs and everything will work out well. I can probably cook up some code to do this (evidently doing it manually would be no better than going through and adding the argument), but it seems like the sort of thing that might be a supported Maven use-case.
Being specific, I'm trying to replace this plugin:
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
...
</plugin>
with this one:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
...
</plugin>
You can do this with two profiles in your pom. One activate by default the other not. Then you can easily select which to use accordingly which profile you choose.
For exemple, here is a older post in the same spirit : How do I exclude a dependency in provided scope when running in Maven test scope?

Resources