Writing a Hudson plug-in (Part 1 – Preparation)This is the first part of a tutorial on writing a Hudson plug-in. The aim of this tutorial is to develop a Publisher for JavaNCSS. This publisher will work with both Hudson Freestyle projects and Hudson Maven2 projects. The publisher will also include a trend graph.Before we can start plug-in development, we need to have a set of working projects to throw at our plugin. Ideally these projects should be simple and quick to build, but the most essential thing is that they build and run the tool that we want to publish the results of! We need a minimum of three projects:Ant-based projectMaven2-based single module projectMaven2-based multiple module projectSo we will develop these three basic projects, get them running the JavaNCSS tool, and then ensure they build in Hudson.The Ant-based projectWe’ll start with the Ant based project. First we’ll need a directory structure:project/ src/ main/ test/ lib/ tools/ javancss/Next we need to download the library dependencies to the lib folder (for example junit.jar) and the custom ant tasks to the appropriate sub-folder of tools.You can get JUnit.jar from http://www.junit.org.The JavaNCSS jars are available at http://www.kclee.de/clemens/java/javancss/ (Note this is the .de domain, not the .com domain). JavaNCSS comes as a zip file, so we’ll just extract the three jar files that we need: ccl.jar, javancss.jar and jhbasic.jarAt this point we should have the followingproject/ src/ main/ test/ lib/ junit.jar tools/ javancss/ ccl.jar javancss.jar jhbasic.jarNext we need a build file, and some sample java files to build. Here is a sample build.xml that will do most of what we want: <pathelement location="${basedir}/tools/javancss/jhbasic.jar" We can then write some simple java classes and test our build. We’ll start with a simple HelloWorld.javapackage com.onedash.hello;/*** A basic hello world application.** @author Stephen Connolly*/public class Hello { public String sayHello(String name) { return “Hello " + name; } public static void main(String[] args) { Hello instance = new Hello(); if (args.length == 1) { System.out.println(instance.sayHello(args[0])); } else { System.out.println(instance.sayHello(“world”)); } }}At this point we should have the following project structure:project/ build.xml src/ main/ com/ onedash/ hello/ Hello.java test/ lib/ junit.jar tools/ javancss/ ccl.jar javancss.jar jhbasic.jarAnd running ANT should give output like:C:\local\project>ant clean distBuildfile: build.xmlclean:[delete] Deleting directory C:\local\project\build[delete] Deleting directory C:\local\project\distcompile: [mkdir] Created dir: C:\local\project\build\classes [javac] Compiling 5 source files to C:\local\project\build\classescompile-tests: [mkdir] Created dir: C:\local\project\build\testcases [javac] Compiling 1 source file to C:\local\project\build\testcasestest: [mkdir] Created dir: C:\local\project\build\testcases\reportsjavancss:[javancss] Generating reportdist: [mkdir] Created dir: C:\local\project\dist [jar] Building jar: C:\local\project\dist\SimpleAntProject.jarBUILD SUCCESSFULTotal time: 3 secondsAnd there should be a javancss-report.xml file in the build directory. That should be enough for an ANT project. Some extra finesse would be to add some more source code so we can examine the structure of the xml report.The Maven2 based single module projectFirst we’ll need a directory structure:project/ src/ main/ java/ test/ java/Next we need a pom.xml to describe the project for Maven2. Here is a simple pom.xml: xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.onedash.hudson SimpleM2Project SimpleM2Project 1.0-SNAPSHOT jar junit junit 4.4 test package org.codehaus.mojo javancss-maven-plugin process-sources report We can reuse the Hello.java from the Ant project, so at this point we should have the following directory structure:project/ pom.xml src/ main/ java/ com/ onedash/ hello/ Hello.java test/ java/And running maven should give the following output:C:\local\project>mvn clean package[INFO] Scanning for projects…[INFO] —————————————————————————-[INFO] Building SimpleM2Project[INFO] task-segment: [clean, package][INFO] —————————————————————————-[INFO] [clean:clean][INFO] Deleting directory C:\local\project\target[INFO] Deleting directory C:\local\project\target\classes[INFO] Deleting directory C:\local\project\target\test-classes[INFO] Deleting directory C:\local\project\target\site[INFO] [javancss:report {execution: default}][WARNING] Unable to locate Source XRef to link to - DISABLED[INFO] [resources:resources][INFO] Using default encoding to copy filtered resources.[INFO] [compiler:compile][INFO] Compiling 1 source files to C:\local\project\target\classes[INFO] [resources:testResources][INFO] Using default encoding to copy filtered resources.[INFO] [compiler:testCompile][INFO] Nothing to compile - all classes are up to date[INFO] [surefire:test][INFO] No tests to run.[INFO] [jar:jar][INFO] Building jar: C:\local\project\target\SimpleM2Project-1.0-SNAPSHOT.jar[INFO] ————————————————————————[INFO] BUILD SUCCESSFUL[INFO] ————————————————————————[INFO] Total time: 5 seconds[INFO] Finished at: Sun Jan 13 22:06:20 GMT 2008[INFO] Final Memory: 5M/10M[INFO] ————————————————————————And there should be a javancss-raw-report.xml file in the target directory.The Maven2 based multi-module projectWe can generate this project in its simplest form just by adding the simple project as a child of a project with pom. We’ll start off with the following directory structure:project/ SimpleM2Project pom.xml src/ main/ java/ com/ onedash/ hello/ Hello.java test/ java/Where the SimpleM2Project subtree is a copy of the previous project. All we now need is a pom.xml to nest this project in: 4.0.0 com.onedash.mvn.hudson MultiM2Project MultiM2Project 1.0-SNAPSHOT pom SimpleM2Project And running maven should give the following output:C:\local\project>mvn clean package[INFO] Scanning for projects…[INFO] Reactor build order:[INFO] SimpleM2Project[INFO] MultiM2Project[INFO] —————————————————————————-[INFO] Building SimpleM2Project[INFO] task-segment: [clean, package][INFO] —————————————————————————-[INFO] [clean:clean][INFO] Deleting directory C:\local\project\SimpleM2Project\target[INFO] Deleting directory C:\local\project\SimpleM2Project\target\classes[INFO] Deleting directory C:\local\project\SimpleM2Project\target\test-classes[INFO] Deleting directory C:\local\project\SimpleM2Project\target\site[INFO] [javancss:report {execution: default}][WARNING] Unable to locate Source XRef to link to - DISABLED[INFO] [resources:resources][INFO] Using default encoding to copy filtered resources.[INFO] [compiler:compile][INFO] Compiling 1 source files to C:\local\project\SimpleM2Project\target\classes[INFO] [resources:testResources][INFO] Using default encoding to copy filtered resources.[INFO] [compiler:testCompile][INFO] No sources to compile[INFO] [surefire:test][INFO] No tests to run.[INFO] [jar:jar][INFO] Building jar: C:\local\project\SimpleM2Project\target\SimpleM2Project-1.0-SNAPSHOT.jar[INFO] —————————————————————————-[INFO] Building MultiM2Project[INFO] task-segment: [clean, package][INFO] —————————————————————————-[INFO] [clean:clean][INFO] Deleting directory C:\local\project\target[INFO] Deleting directory C:\local\project\target\classes[INFO] Deleting directory C:\local\project\target\test-classes[INFO] Deleting directory C:\local\project\target\site[INFO] [site:attach-descriptor][INFO][INFO][INFO] ————————————————————————[INFO] Reactor Summary:[INFO] ————————————————————————[INFO] SimpleM2Project ………………………………… SUCCESS [7.240s][INFO] MultiM2Project …………………………………. SUCCESS [2.754s][INFO] ————————————————————————[INFO] ————————————————————————[INFO] BUILD SUCCESSFUL[INFO] ————————————————————————[INFO] Total time: 10 seconds[INFO] Finished at: Sun Jan 13 22:16:37 GMT 2008[INFO] Final Memory: 7M/15M[INFO] ————————————————————————And there should be a javancss-raw-report.xml file in the SimpleM2Project/target directory.The Hudson setupWe’ll start by running mvn hpi:create to create a base to work from:C:\local>mvn hpi:create[INFO] Scanning for projects…[INFO] Searching repository for plugin with prefix: ‘hpi’.[INFO] —————————————————————————-[INFO] Building Maven Default Project[INFO] task-segment: [hpi:create] (aggregator-style)[INFO] —————————————————————————-…[INFO] [hpi:create]Enter the groupId of your plugin: org.jvnet.hudson.plugins[INFO] Defaulting package to group ID: org.jvnet.hudson.pluginsEnter the artifactId of your plugin: javancss…[INFO] ————————————————————————[INFO] BUILD SUCCESSFUL[INFO] ————————————————————————[INFO] Total time: 2 minutes 44 seconds[INFO] Finished at: Sun Jan 13 22:34:58 GMT 2008[INFO] Final Memory: 8M/15M[INFO] ————————————————————————The result should be a sub-directory called javancss with a pom.xml file and a basic Hudson plugin starting point. We’ll edit the pom.xml to update the version of Hudson to the latest (at the time of writing 1.170) and launch a live development instance to set our projects up in.Open up the pom.xml file, and change the 1.153 tags for the hudson-core and hudson-war dependencies to 1.170.The dependency section should now look like this: org.jvnet.hudson.main hudson-core 1.170 provided org.jvnet.hudson.main hudson-war war 1.170 testNext launch a copy of Hudson by running mvn hpi:runC:\local\javancss>mvn hpi:run[INFO] Scanning for projects…[INFO] Searching repository for plugin with prefix: ‘hpi’.[INFO] —————————————————————————-[INFO] Building Unnamed - org.jvnet.hudson.plugins:javancss:hpi:1.0-SNAPSHOT[INFO] task-segment: [hpi:run][INFO] —————————————————————————-[INFO] Preparing hpi:run…[INFO] Started Jetty Server[INFO] Starting scanner at interval of 1 seconds.Now fire up a web browser for http://localhost:8080/We want to create five projects: Freestyle project for the Simple Ant projectFreestyle project for the Single module Maven2 projectFreestyle project for the Multi-module Maven2 projectMaven2 project for the Single module Maven2 projectMaven2 project for the Multi-module Maven2 projectFor extra finesse, we can add a slave executor, and create a second set of these projects tied to the slave. An final extra project that does nothing other than trigger all the other projects to build is the icing on the cake.
/ Writing a Hudson plug-in (Part 1 – Preparation)
Created Sun, 13 Jan 2008 00:00:00 +0000
Modified Sun, 13 Jan 2008 00:00:00 +0000