Jenkins : Maven 3 support in Hudson

Maven 3 support in the native maven plugin has been integrated in 1.392

Documentation in progress

Introduction

Maven 2 support in Hudson is still experimental, but many users rely on it. Maven 3 comes now with first beta available, we have to consider support in Hudson as many things changed and it cannot be integrated to Hudson the way Maven 2 was.

Maven support in Hudson

Maven 2 support in Hudson is a two-phase process :

  1. Read project POM(s), build the module tree assuming dependencies ordering, and setup jobs for thoses modules
  2. Run maven build on modules

In early stages, First step was built on Maven Embedder, but this strategy failed due to lack of support for settings and other issues. The project POMs are now parsed by Hudson using maven model API.

Second step uses a hack to create the classloader hierarchy expected by Maven, but include Hudson tweaks (custom plexus components, plugin filters, phase listeners) so that Hudson can monitor the build. As a result, some maven builds in hudson can behave strangely compared to command line maven (JIRA issues #?).

Why do we have to integrate Maven into Hudson?

What is the main benefit for integrating Mavens internal structures into Hudson? What do Hudson gain from that compared to viewing Maven as a black box and just make sure that Hudson can install and find Maven 3 and call it's target as any user would do?

Better feedback

Many maven projects are built as multi-module projects. Running the build as a black-box process with a single success/failure status gives few feedback on build status. By analyzing the POM and modules, Hudson can display status per module, with related links to test failures and other reporting stuff. Hudson can also setup the maven options to only build modules that are related to last commit and the dependent ones (incremental build option) OR build modules in parallel fo a quicker build.

Possible improvements to Maven 3 support

Project analyzis

This step can take advantage of new Maven 3 API and "build plan" (doc) to get a clean view of the project structure, without dependency on maven internals. Using such API the Maven version and configuration used to analyze the project and to run the build will be the same

Running maven 3 build

This step requires a better isolation from Hudson JVM with less changes to Maven runtime.

Maven 3 has cleaner APIs and support for listeners (used in maven parallel build, to be confirmed|link to doc?). Running the Maven3 build as a standalone JVM - like freestyle projects in hudson - will make it more compliant to standard Maven build. The forked JVM just has to include a Hudson dedicated listener to send back build notifications to Hudson JVM, but the JVM running Maven will require no other hack.

Change in Hudson Plugins for maven 3

@since 1.392 MavenBuildProxy has a new method getMavenVersion() which returns a bean MavenBuildInformation.
This bean returns the maven version used for this build with the method String getMavenVersion().
Here you are able to know if you are using maven 2 or later with this piece of code :

public boolean maven3orLater(String mavenVersion) {
    // null or empty so false !
    if (StringUtils.isBlank( mavenVersion )) {
      return false;
     }
     return new ComparableVersion (mavenVersion).compareTo( new ComparableVersion ("3.0") ) >= 0;
}

So now all MavenReporter knows the maven version used.
If you are modifying the mojo execution in your maven reporter you have to take care of the following change to (see related issues : JENKINS-8415, JENKINS-8362 )

See relative commit https://github.com/jenkinsci/jenkins/commit/3f2ab68b248a8104053227b074221937f7ab3176
Now in order to change (when your build is maven 3), you must play with the mojo configuration available with :

mojo.mojoExecution.getConfiguration()
This is a Xpp3Dom now (previously it was a XmlPlexusConfiguration )