Maven release and versions maven plugin - maven

What is the numbering/versioning strategy for dependencies when doing snapshots/releases?
A team of 15 developers,20 Maven parent projects = total 70+ POMs including child module POMs. Currently there are a lot of dependencies where most of these 70 depend on one or the other.
Past:
All POMS have 1.0.0-SNAPSHOT as their version and also under dependencies tags.It gets uploaded to Nexus repo with mvn deploy.
Present:
We started doing mvn release recently. So all 20 parent POMs are now 1.0.1-SNAPSHOT and release ver 1.0.0 for all of them lies in Nexus.All <dependencies> tags now point to 1.0.0
Problem:
Developers don't want to point to release versions. They need bleeding edge development version 1.0.X-SNAPSHOT from their peers whether its unstable or not.
SCM wants to point to RELEASE versions only as he has to do a mvn release once a week which will fail as it points to snapshot versions.
Question:
Now I know the version plugin , but the question is, what do I put in the POM so that both parties are satisfied by running their own version of mvn versions: command. Preferably, the POMs should point to SNAPSHOTS so 15 people are happy, and when SCM does the release, he can run a mvn versions:something and everything gets converted to RELEASE versions in place of SNAPSHOTS. Then back to SNAPSHOTS for developers.

I am putting this as an answer, even though at present this is not quite working answer.
When I added the completionGoals configuration option in the Maven Release Plugin, my aim was to enable the work-flow where development used version ranges, but that releases would be pinned to concrete versions only.
One of the enabling goals that was added to the Versions Maven Plugin was the versions:resolve-ranges goal. What is missing is a way to unresolve those ranges again afterwards.
We don't really have anywhere safe to stash the originating ranges that the release plugin will not object to or clean up before we need it again.
The closest solution I have thought of is to inject XML PI's beside the version containing the version range... in such a situation, the pom.xml would get transformed from, e.g.
<project>
...
<dependencies>
...
<dependency>
<groupId>com.foo.bar</groupId>
<artifactId>manchu</artifactId>
<version>[1.2.3,2.0)</version>
</dependency?
...
</dependencies>
...
</project>
to
<project>
...
<dependencies>
...
<dependency>
<groupId>com.foo.bar</groupId>
<artifactId>manchu</artifactId>
<version>1.5.7</version>
<?versions-maven-plugin allowed-version-range="[1.2.3,2.0)"?>
</dependency?
...
</dependencies>
...
</project>
by ensuring that the preparationGoals included the versions:resolve-ranges goal... (Note: the versions plugin might have to fork a third Maven to work around the lack of pom.xml reloading in order to have the clean verify be meaningful, though resolve-ranges is supposed to resolve in the exact version that the build is working with, so it shouldn't be an issue).
Then in completionGoals you have the (as yet unimplemented) versions-maven-plugin goal that removes the XML PI's and puts the ranges back in place.
There are a number of issues preventing this at present:
Unsure if the Maven Release Plugin's pom rewriting will remove the XML PI's (needs testing to confirm)
The XML parsing library in versions-maven-plugin is hacky at best, and a better solution is needed to enable the XML PI injection
My son demands attention, leaving very little time for me to attend to these issues.
However, you might be able to codge something together.
Set completionGoals to something like versions:use-next-snapshots versions:commit
Run your releases like so mvn versions:use-releases versions:commit scm:commit release:prepare release:perform install
So what should happen:
We switch the -SNAPSHOTs to releases
We commit the change to SCM
We start the release preparation
When the pom.xml is transformed to the next development version, we also advance the dependencies (using the fact that all our dependencies had the exact same command (with the install at the end) so their next -SNAPSHOT is already in the local repository, so they will get advanced for us automatically (in theory)) and we rely on release:prepare to commit the changes for us.
The release is performed as normally
We install the next development -SNAPSHOT into the local repo so that all the down-stream projects will get their version of this updated when they run versions:use-next-snapshots
The above is slightly error prone... I'd far prefer if I could offer you the version range based solution, but, well right now this is the best solution I can see.

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.

maven release plugin and multiple projects in separate git repositories with Jenkins

I’ve found quite a few hints about the maven-release-plugin, multi-module, multi-project, parent POMs, etc. but they all don’t quite fit what I have:
I have several projects (the reduced case is two: project-common and project-impl) that are somewhat separate from each other, and developed in separate git repositories, but usually released together. For this purpose, project-common/pom.xml contains:
<groupId>de.tarent.example</groupId>
<artifactId>project-common</artifactId>
<version>1.5.1.4-SNAPSHOT</version>
… and project-impl/pom.xml contains:
<groupId>de.tarent.example</groupId>
<artifactId>project-impl</artifactId>
<version>1.5.1.4-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>de.tarent.example</groupId>
<artifactId>project-common</artifactId>
<version>${project.version}</version>
</dependency>
There is no parent POM.
The idea here is to generally use the version of project-common for them all, but be able to occasionally do individual releases of only one project; in those cases, the dependency version would, of course, have to be manually changed, but that’s okay.
Now, we’re using Jenkins’ “Perform Maven Release” to create our releases. (Well, we wish to. The projects were until recently not releasable, so our developers built them by hand, complete with temporary files, unused files, local changes, LDAP passwords in XML configs, editor .swp files, etc. – you can see why I was tasked to change this, despite not knowing Java™ or Maven or Jenkins. Or maybe, because of it.)
The release of project-common goes without a hitch, but project-impl fails at the very first phase, checking that there are no SNAPSHOT dependencies. Well duh. (There are none except the project-common one.) Overriding the maven-release-plugin to skip the SNAPSHOT check is impossible. Using a parent POM does not work here either, as these are completely separate repositories and, on occasion, released independently. So, how to do this while retaining the Jenkins and Maven Release comfort?
Continue on to: Answer your own question – share your knowledge, Q&A-style…
Reading logs, I figured out that Jenkins invokes Maven like this:
mvn -B -f /var/lib/hudson/jobs/project-impl/workspace/pom.xml \
-DdevelopmentVersion=1.5.1.5-SNAPSHOT -DreleaseVersion=1.5.1.4 \
-Dtag=1.5.1.4 -Dresume=false release:prepare release:perform \
-DpreparationGoals=clean install -e
The -D had to be good for something, right? Could I do ${project.version:-${releaseVersion}} like in shell, I asked a coworker (thanks Umer!), who said, not like that, but -D overrides properties.
That stopped me short for a bit: I could not place the version into the property, because the maven-release-plugin only updates the project <version> element.
Thankfully, double indirection works. While an ugly hack, and it will break if someone does not use Jenkins to release, or if someone uses -DreleaseVersion locally, two little changes made those projects releasable:
First, we add a property called releaseVersion which defaults to the (dynamically updated) ${project.version}:
<properties>
<releaseVersion>${project.version}</releaseVersion>
</properties>
Then, we change the dependency to use that instead:
<dependency>
<groupId>de.tarent.example</groupId>
<artifactId>project-common</artifactId>
<version>${releaseVersion}</version>
</dependency>
The only other problem I can see with this solution is if some{one,thing} uses the released POM from the Maven repository, as it also contains this indirection (we don’t filter the POMs on release). But it works well, so far.
And if there is a need for project-impl, one will just change the <version>${releaseVersion}</version> line to <version>1.5.1.4</version> manually, just like before (ceteris paribus).

about generate maven dependency

I am pretty new to maven.
Now I have a maven project developed. My another project needs to depend on this one.
Does anyone know how can I generate my own dependency? So that my second project can add the first one as a dependency in pom.
thank you very much
Since your first project is already a maven-project, just install it in your local repository by running mvn install in the first project's root directory.
Then you can include a dependency in your second project by simply referencing the groupId, artifactId and version you defined in the first project.
So if your first project had the following in its pom:
<project>
<groupId>com.yourdomain</groupId>
<artifactId>yourcomponent</artifactId>
<version>1.0</version>
... <!-- more here -->
you can include this in your second project:
<dependencies>
<dependency>
<groupId>com.yourdomain</groupId>
<artifactId>yourcomponent</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Unless you deploy your project 1 jar to a central maven repository, this will only work if your jar is in your local repository (via mvn install).
Maven projects are identified by the "Maven coordinates", that is, the ArtifactID, GroupID and version.
Say you create your first project and run maven install. Your local repository (in $HOME/.m2/) will now contain the compiled project plus whatever coordinates you put in there.
Your second project must now only depend on the said coordinates.
I would suggest googling a bit on maven. I made a tutorial a long time ago that might help you, even if the examples are a little simple. Here you go and good luck!

How can I deploy only the pom file to my snapshot repository in Maven?

I would like to be able to deploy only the POM artifact (file) without the main artifact (JAR, WAR, etc), when running mvn deploy and version is a SNAPSHOT version.
Why?
We several developers working on multiple Maven projects. We have a Hudson server with a job per Maven project and version (e.g. foo-1.2, foo-1.3). Each job builds the project and deploys it to a Nexus server (upon success). Maven projects under development are marked as such by using -SNAPSHOT postfix in the version. For example: 1.2-SNAPSHOT, 1.3-SNAPSHOT.
Here's a sample scenario how a developer work is damaged due to this architecture.
Assume two Maven projects: foo-core and foo-webapp, both at version 1.2-SNAPSHOT.
Developer A is working on foo-core, made several changes and compiled it.
Developer A continues to work, but on foo-webapp.
Developer B started working and changing foo-core. It commits his work and pushes it to the SCM.
Hudson is triggered by SCM; Builds foo-core and deploys it to the snapshot repository in Nexus.
Developer A is running mvn install on foo-webapp. Maven is checking with Nexus, and finds that there is a newer version of foo-core in Nexus. It downloads it (filled with developer B changes) and than it fails compilation, since the changes made by developer A are not in the jar located in the local repository. The download overrides the file installed there by developer A.
Existing Solutions
I looked into maven-deploy-plugin, but this plugin deploys all artifacts attached to the project. If they had a way to configure which artifacts to deploy, it would have been great.
Question: Is there any way to solve this without resorting to writing my own deploy plugin, based on maven-deploy-plugin?
Basically to the -Dfile parameter, instead of the artifact, pass the pom.xml. Run the command and yay! mvn deploy won't give you any issues now. Here's a sample deploy command :
$ mvn deploy:deploy-file -DpomFile=pom.xml -Dfile=./pom.xml -DgroupId=my.group.id -DartifactId=artifact-id -DrepositoryId=bigdata-upload-snapshots -Durl=http://maven.mymaven.com/content/repositories/snapshots/
A prerequisite for this is that the repository be added in your settings.xml
[Edit]: I have supplied the parameters -DgroupId and -DartifactId of the project in the sample deploy command but they're not required (refer to Zac's comment below)
I never heard of such a possibility and also would be very astonished if that would be possible. As the pom and the resulting artifact are some kind of unit it would make no scence (to me) to deploy only parts of them.
Nevertheless you should consider to make a separate pom project which specified dependencies and plugins you might want to use on your JAR/WAR projects like this:
<groupId>foo.bar</groupId>
<artifactId>my-pom</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
and then inherit that pom project by your JAR/WAR projects like this:
<parent>
<groupId>foo.bar</groupId>
<artifactId>my-pom</artifactId>
<version>1.0.0</version>
</parent>
This is called project inheritance. You can change and deploy your pom project independent of the "child" artifacts.
EDIT after reading motivation:
As I understand you want to prevent maven to resolve SNAPSHOT artifacts from a repository (so that local version won't be overwritten). Have you ever tried to use the mvn -nsu option (see mvn -help)?
-nsu,--no-snapshot-updates Suppress SNAPSHOT updates
I never tried it but found this reported issue. Nevertheless I would give it a try (as the issue is not commented yet).
This works for me for deploying a pom file only (e.g next to an existing jar):
(Note: you need to specify packaging also, otherwise it will be uploaded as an .xml file which is not what you want.)
mvn deploy:deploy-file \
-Dfile=pom.xml \
-Dpackaging=pom \
-DgroupId=com.mycompany.package \
-DartifactId=my-artifact \
-Dversion=2.0.1 \
-DrepositoryId=serverIdFromSettingsXMLForCredentials \
-Durl=http://repositoryserver/myrepo/
Not exactly the answer these folks were asking for. My situation was I wanted to deploy only the parent pom. I'm using the spring-boot-thin-layout in a child module. This requires the parent module be deployed into artifactory. I added the following into my project. It enables skipping of install and/or deploy phase.
In my parent pom:
<properties>
<disable.install>true</disable.install>
<disable.deploy>true</disable.deploy>
<enable.deployAtEnd>true</enable.deployAtEnd>
</properties>
<profiles>
<profile>
<id>deploy-parent</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<disable.install>true</disable.install>
<disable.deploy>true</disable.deploy>
<deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>
<build>
<finalName>${project.version}</finalName>
</build>
</profile>
</profiles>
And the in my child pom(s) or any module you don't want deployed with parent:
<properties>
<maven.install.skip>${disable.install}</maven.install.skip>
<maven.deploy.skip>${disable.deploy}</maven.deploy.skip>
<deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>
So effectively when I run mvn deploy on the parent pom, it will compile all the modules, not run install on anything, and then at the end deploy any module not having `

Resources