Wednesday, 22 September 2010

Use maven 3 apis in a hudson plugin

Using maven 3 apis in a hudson needs to change classLoader hierarchy as hudson load some old maven artifacts in the parent classLoader.
So the solution is to use a child first classLoader.
This new classLoader has been introduced in hudson 1.378. (see HUDSON-5360).
So you can now use it to made your plugin dependencies win on hudson core classLoader.
Some steps are needed.
Configuring your hpi plugin

<plugin>
<groupid>org.jvnet.hudson.tools</groupid>
<artifactid>maven-hpi-plugin</artifactid>
<version>1.54</version>
<configuration>
<pluginFirstClassLoader>true</pluginFirstClassLoader>
</configuration>
</plugin>

So now your pluginWrapper.classLoader will be of type PluginFirstClassLoader.

// pluginId is project.artifactId from your plugin pom
PluginWrapper pluginWrapper = Hudson.getInstance().getPluginManager().getPlugin( pluginId );
PluginFirstClassLoader pluginFirstClassLoader = (PluginFirstClassLoader) pluginWrapper.classLoader;


Now everthing is ready but some other tricks are needed :-)

Create a PlexusContainer (note you must use the new "plexus-guice" bridge).
This means you need the following dependency :

<dependency>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-inject-plexus</artifactId>
<version>1.4.1</version>
</dependency>

And very important you must exclude dependencies from the original plexus-container

<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-connector-wagon</artifactId>
<version>${aetherVersion}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
</exclusion>
</exclusions>
</dependency>


To prevent this you can add an enforcer rule which will chech plexus-container-default inclusion

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0-beta-1</version>
<executions>
<execution>
<goals>
<goal>enforce</goal>
</goals>
<phase>validate</phase>
<id>ensure-no-plexus-container</id>
<configuration>
<rules>
<bannedDependencies>
<excludes>
<exclude>org.codehaus.plexus:plexus-container-default</exclude>
</excludes>
<message>
ensure-no-plexus-container doesn't work anymore with maven 3 librairies. you have to add some exclusions.
</message>
</bannedDependencies>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>


How to create the PlexusContainer from the PluginFirstClassLoader :

private PlexusContainer getPlexusContainer(PluginFirstClassLoader pluginFirstClassLoader) throws PlexusContainerException {
DefaultContainerConfiguration conf = new DefaultContainerConfiguration();
ClassWorld world = new ClassWorld();
ClassRealm classRealm = new ClassRealm( world, "project-building", pluginFirstClassLoader );
// olamy yup hackish but it's needed for plexus-shim which needs a URLClassLoader and PluginFirstClassLoader is not
for ( URL url : pluginFirstClassLoader.getURLs() )
{
classRealm.addURL( url );
LOGGER.fine( "add url " + url.toExternalForm() );
}
conf.setRealm( classRealm );

return new DefaultPlexusContainer( conf );
}


Then set the current Thread classLoader (don't miss to restore the original one in a finally statement

PlexusContainer plexusContainer = getPlexusContainer( pluginFirstClassLoader );

Thread.currentThread().setContextClassLoader( plexusContainer.getContainerRealm() );


Now you can play with maven 3 apis

ProjectBuilder projectBuilder = plexusContainer.lookup( ProjectBuilder.class );


A first sample is the plugin called : maven-dependency-update-trigger
: sources and Wiki Page (under construction :-) )
You must have a look at the dependencies used.

The plugin will check your project according to a cron expression and schedule a build if a snapshot dependency has changed (dependency and plugin).

It will be released as son as hudson 1.378 will be released.

Note : hpi:run doesn't work yet for this plugin as it needs some changes in the hpi mojo to handle the new PluginFirstClassLoader.

Thursday, 9 September 2010

Searching new challenge

Hi,
I'm currently searching new challenge for my work life.
And why not a kind of new life.
If you don't know me : my work or my opensource life.
You will find a resume here http://people.apache.org/~olamy/resume/.
Note as I'm a opensource/maven addict it's in a maven format.
The license is very flexible.
So feel free to fork or distribute this resume :-).

--
Olivier

Maven site plugin 3.0-beta-2 for maven release

Hi,
A new version of the maven-site-plugin for maven 3 has been released.
See announce [ANN] Release Maven Site Plugin 3.0-beta-2 for maven 3.
It works only with last core beta-3.

Have Fun !
--
Olivier