How to really know the last version of a jar using Maven display-dependency-updates - maven

Maven provides a plugin (versions-maven-plugin) that allows to retrieve the latest available versions for all the dependencies of a project.
However, the result is polluted by dependencies when their naming scheme has evolved over time.
Perfect example of this is commons-beanutils. I get this result in Maven:
[INFO] --- versions-maven-plugin:2.5:display-dependency-updates (default-cli) # dataimport ---
[INFO] The following dependencies in Dependencies have newer versions:
[INFO] commons-beanutils:commons-beanutils ......... 1.9.3 -> 20030211.134440
The real last version (as of this writing) is 1.9.3, but back in 2003, version number was based on a timestamp.
Is there a workaround that would allow the Maven plugin to get the real last version? By ignoring a range of versions?
Until I find a solution, I can't reasonably use the Maven feature allowing to automatically update all dependencies.
Googling about this problem, it looks like no one complains about it - and as a result the version 20030211.134440 is still heavily used while quite old.

You can use parameter rulesUrl to pass to this plugin path to file with rules of version comparision.
See http://www.mojohaus.org/versions-maven-plugin/use-latest-versions-mojo.html#rulesUri .
Format of this file you can see there: http://www.mojohaus.org/versions-maven-plugin/rule.html .

Related

How do I get the maven dependency:tree command to show when I'm using a RELEASE version?

I'm using the maven dependency:tree command to see all my modules and submodules.
We're using a dev=RELEASE version model so that we can see our dependencies fail fast. Then we lock in a version when we go to prod.
Our dependency tree goes about four levels deep of modules.
I want a quick way to identify if anything in my pom dependencies contains a RELEASE version.
I'd like to be able to use the dependency:tree command to do this - but unfortunately it resolves all the RELEASE versions to the last 'dot' version.
Note this is using Maven 2.
My question is: How do I get the maven dependency:tree command to show when I'm using a RELEASE version?
The trick is - as the comments have pointed out - is to upgrade to Maven 3 - and then use the Maven Versions Plugin :
This means you have to set the versions explicitly - but you still get the fail-fast behaviour.
See here for more detail:
https://stackoverflow.com/a/48184999/15441

How does Maven decide what version of a plugin to use, when you don't specify any?

I recognized that Maven not always uses the latest version of a plugin.
For example org.codehaus.mojo:sonar-maven-plugin version 2.7 has beed released on 19th of October but on 23th of October, 2.6 was still used by Maven (mvn sonar:sonar).
I even remember some plugins, where the latest version was several minor releases above the version that Maven decided to use.
Is there any (central) index/list/database where Maven looks up what version to use? If yes, where can it be accessed manually?
I know this is an ancient thread but in the interest of posterity and accuracy: all pom.xmls logically inherit from the super POM. You can always see what your "real" pom.xml looks like by typing:
mvn help:effective-pom
The resulting pom.xml that is printed is a combination of the super POM, your pom.xml, and of course any parent POMs in the mix as well.
The super POM is provided by the org.apache.maven.model.superpom.DefaultSuperPomProvider class (https://github.com/apache/maven/blob/bce33aa2662a51d18cb00347cf2fb174dc195fb1/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java#L56-L85). The resource it loads is org/apache/maven/model/pom-4.0.0.xml (https://github.com/apache/maven/blob/bce33aa2662a51d18cb00347cf2fb174dc195fb1/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml#L23-L149).
As far as i know, this link will answer your question.
Automatic Plugin Version Resolution
When a plugin was invoked without an explicit version given in the POM
or on the command line, Maven 2.x used to pick the latest version
available where the latest version could either be a release or a
snapshot. For the sake of stability, Maven 3.x prefers the latest
release version over the latest snapshot version.
Given the threat of non-reproducible builds imposed by automatic
plugin version resolution, this feature is scheduled for removal as
far as plugin declarations in the POM are concerned. Users of Maven
3.x will find it output a warning when missing plugin versions are detected to encourage the addition of plugin versions to the POM or
one of its parent POMs. The Enforcer rule requirePluginVersions can be
used additionally check for missing plugin versions in the POM
For command line execution if a version is not specified Maven looks up the latest version from the GA (group ID/artifact ID) maven-metadata.xml file.
Example: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-clean-plugin/maven-metadata.xml
If you're encoding command line execution of Maven goals into your builds you should specify a version for these, otherwise your builds may change as new versions of plugins are released.

Spring-core dependency version error with a Jenkins Plugin

I'm trying to make a Jenkins plugin that uses a library that requires spring-core 3.2.2 (cloudfoundry-client-lib). I simply used the mvn command to create a skeleton plugin, then added my Maven dependency to pom.xml and a few simple code lines that uses the library. I'm not getting any problem running the skeleton plugin without my dependency.
Upon compiling with "mvn package", I'm getting a test error:
WARNING: Failed to scout hudson.security.PAMSecurityRealm
java.lang.InstantiationException: java.lang.NoClassDefFoundError: org/springframework/core/env/EnvironmentCapable
Looks like this is a class that appeared in spring-core 3.1.0. So I looked at the Maven dependency tree:
[INFO] --- maven-dependency-plugin:2.3:tree (default-cli) # stackato-jenkins ---
[INFO] org.wiwiweb:cf-test-jenkins:hpi:1.0-SNAPSHOT
[INFO] \- org.cloudfoundry:cloudfoundry-client-lib:jar:1.0.2:compile
[INFO] \- org.springframework:spring-webmvc:jar:3.2.2.RELEASE:compile
[INFO] \- org.springframework:spring-core:jar:2.5.6.SEC03:compile
So Maven tells me it's using spring-core 2.5.6 because of spring-webmvc 3.2.2? This is strange because, looking online, spring-webmvc 3.2.2 depends on spring-core 3.2.2. Looking at the verbose version of the tree, looks like jenkins-core depends on spring-core 2.5.6... This makes me suspicious that the problem is from Jenkins.
Anyway, if it's just a version conflict, then overriding Maven's decision by explicitly saying I want spring-core 3.2.2 in my pom.xml should solve the problem, right?
I did this, then did not get a compile error. Problem solved!... not.
In runtime, after activating this plugin in Jenkins and running a build with this, as soon as the code runs into a line that uses the library I added, the Jenkins output tells me this:
FATAL: org.springframework.util.CollectionUtils.unmodifiableMultiValueMap(Lorg/springframework/util/MultiValueMap;)Lorg/springframework/util/MultiValueMap;
java.lang.NoSuchMethodError: org.springframework.util.CollectionUtils.unmodifiableMultiValueMap(Lorg/springframework/util/MultiValueMap;)Lorg/springframework/util/MultiValueMap;
UnmodifiableMultiValueMap() is a method that was added in spring-core 3.1, so this means Jenkins is still trying to run my plugin with the old version of spring-core, even though I explicitly said I wanted the newest one in my plugin's pom.xml!
So I'm stuck on this. I'm not even sure if it's a Maven or a Jenkins issue. I'll sum up the whole thing in two questions:
Why is Maven not compiling the plugin with a correct version of spring-core unless I explicitly tell him to? It should be able to follow dependencies without me giving it hints.
Why is Jenkins running my plugin with an older version of spring-core than the one it was compiled with, and how can I make it use the correct one?
If you're picking up dependencies from the Jenkins install rather than from your plugin the solution is actual quite easy to implement. Per the Jenkins documentation, simply add the maven-hpi-plugin to the build in the pom.xml of your Jenkins plugin and set it to load the plugin classes first:
<build>
<plugins>
<plugin>
<groupId>org.jenkins-ci.tools</groupId>
<artifactId>maven-hpi-plugin</artifactId>
<configuration>
<pluginFirstClassLoader>true</pluginFirstClassLoader>
</configuration>
</plugin>
</plugins>
</build>
Try to "shade" the CF client lib using the Maven Shade plugin, as it seems Jenkins doesn't like plugins that are using a different version of Spring than the one it uses internally itself.
Even if your own plugin doesn't use Spring directly, but the CF library does, I believe this still applies. The person that suggested shading in the jenkinsci-dev mailing list seems to be involved in Jenkins plugins development, so he might know about this more than others.
These being said, I would get the source code for cf-client-lib, I would change the pom.xml to consider shading for org.springframework package, as well (because cf-client-lib already uses shading for org.codehaus.jackson package) and I would use this "shaded" version of cf-client-lib in the Jenkins plugin.

Maven release plugin ignores releaseVersion attribute

I'm trying to create a svn branch from the trunk which has the version of TRUNK-SNAPSHOT in its pom and children's pom files with this command:
mvn --batch-mode release:branch -DbranchName=15.1 -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false -DreleaseVersion=15.1
However I'm getting this error:
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error parsing version, cannot determine next version: Unable to parse the version string: "TRUNK-SNAPSHOT"
While it's obvious that it was not able to calculate the next version of TRUNK-SNAPSHOT, why would the plugin ignore the releaseVersion argument that I wanted it to use for the new branch instead of trying to calculate the next version from the trunk's version identifier?
Although running in interactive mode allows me to provide the version for the new branch, I'll need it work in the batch mode. Is there any other way I can specify the new branch version in the batch mode regardless of what the branching source (trunk) version is?
Update 1: The plugin version I use is 2.0-beta-8
This was fixed in 2.4 as part of https://issues.apache.org/jira/browse/MRELEASE-511

Maven uses different timestamps when building snapshot artifacts in a large project

We have a large maven 3 project with around 250 modules. All modules have version 1.0-SNAPSHOT and modules tree has single parent module with the same version as a tree root.
Project is built with Bamboo nightly and artifacts are installed to a Nexus repository using command "mvn clean install".
It happens that part of modules are built with one timestamp while the rest with the other, something like:
module1-1.0-20121127.150154-7.jar
module100-1.0-20121127.150527-7.jar
In another project I was trying to set dependency to artifacts of this project using specific version of a snapshot dependency (as discussed in this question Maven specific version of a snapshot dependency) but failed to build due to the problem described above.
Does anyone know why maven would use different timestamps and how to fix that?
MNG-6754 was finally fixed in 3.8.2.

Resources