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


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 :


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


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

ensure-no-plexus-container doesn't work anymore with maven 3 librairies. you have to add some exclusions.

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

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
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 :-).


Maven site plugin 3.0-beta-2 for maven release

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 !