Sunday, March 28, 2010

Running JavaDoc/JUnit/Emma on Hudson using Buckminster

Last week I wrote about "Building Products with Buckminster/Hudson", today I want to share some of my experience about my JavaDoc job, running JUnit tests and Emma code coverage.


My goal was to generate JavaDoc for our framework softmodeler and the server/client application.

A short overview about the checkout sources:

To prevent errors (some errors prevent JavaDoc from creating the index.html and related files) it's important to set the classpath, in my case the target platform. So I pass the location of the target platform and use a fileset to get all the jars together. This path is then referred using classpathref="files-classpath" in the javadoc call.

If you get errors about too long filenames and such, make sure you use useexternalfile="true", more information on that here.
For the actual Javadoc task I use a bunch of filesets, excluding some unwanted packages.

Here the ant "create.javadoc" target:

<target name="create.javadoc" description="Generate the JavaDoc for the sources">
<echo message="javadoc source ${source}"></echo>
<echo message="javadoc destination ${javadoc.output}"></echo>
<echo message="target platform ${target.platform}"></echo>

<!-- set target platform as classpath -->
<path id="files-classpath">
<fileset dir="${target.platform}">
<include name="*.jar"/>

<!-- clean and create output location -->
<delete dir="${javadoc.output}"/>
<mkdir dir="${javadoc.output}"/>

<!-- generate the javadoc -->
windowtitle="Scodi/Softmodeler Documentation">
<!-- link external APIs -->
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>
<link offline="false" href=""/>

<!-- softmodeler sources -->
<fileset dir="${source}/softmodeler/plugins/" defaultexcludes="true">
<include name="**/*.java"/>
<exclude name="**/org/**"/>
<exclude name="**/net/**"/>
<exclude name="**/test/**"/>

<!-- scodi sources -->
<fileset dir="${source}/scodi-server/plugins/">
<include name="**/*.java"/>
<exclude name="**/test/**"/>
<fileset dir="${source}/scodi-rcp/plugins/">
<include name="**/*.java"/>
<exclude name="**/test/**"/>
<exclude name="ch.scodi.mig/**"/>

<bottom><![CDATA[<i>Copyright © 2007 henzler informatik gmbh, CH-4106 Therwil</i>]]></bottom>

To be able to launch the ant task from Buckminster I had to add the following action to buckminster.cspex:

<cs:public name="create.javadoc" actor="ant">
<cs:property key="buildFile" value="build/javadoc.ant">
<cs:property key="targets" value="create.javadoc">
<cs:property key="source" value="${workspace}source">
<cs:property key="javadoc.output" value="${workspace}javadoc">

The Hudson job then needs to checkout the source and run a build step "Run Buckminster":

import '${WORKSPACE}source/scodi-rcp/features/'

perform -D workspace=${WORKSPACE} -D target.platform=${WORKSPACE}../../target.platform/workspace/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool/plugins/

I know the target.platform path is ugly, didn't find a pre-defined variable. Tried ${targetPlatformPath} but that somehow didn't work, any hints?

You then can publish the JavaDoc using the "Post-Build-Action".

Junit & Emma

Buckminster provides the command "junit" which allows you to launch "JUnit Plug-In Tests". This is a really great feature, because you can run tests in your eclipse environment very easy.
I ran into some problems because my launch file was not found, the launch needs to be within your workspace (not your checkout sources).
I imported my product site.query and did not realize that my test feature (containing the launch file) was not part of that. So additionally I had to import my test feature (see below) and it worked.

import '${WORKSPACE}source/scodi-server/features/'
import '${WORKSPACE}source/scodi-server/features/'


perform -D target.os=* -D* -D target.arch=* -D qualifier.replacement.*=${version}
perform -D target.os=win32 -D -D target.arch=x86

junit -l '/' -o '${WORKSPACE}output/junit_result.xml'

There is a "Post-Build-Action" to publish JUnit results. It somehow does not work with the generated output and caused my build to fail.
A great alternative is the "Performance Plugin", which publishes your result and also performance trends.

Martin Taal, founder and lead of the EMF Teneo project, wrote a very useful wiki article about Teneo building with Buckminster and Hudson.
Interesting for me was the Emma part.
To get Emma coverage reports do the following:
- Install the Emma Plug-In
- Install to the Buckminster installation
- change the "junit" command to "emma"
- add an additional paramter for the coverage report
- Your done. Awesome!!!

emma -l '/' -o '${WORKSPACE}output/junit_result.xml' --xml '${WORKSPACE}/output/coverage_report.xml' --flatXML

The Emma "Post-Build-Action" then publishes your coverage report.

Buckminster and Hudson, a great combination which makes releng of eclipse based products so much easier. Thanks to the Buckminster team!!!


Achim Demelt said...

It's always great to read first-hand experience reports from users. Thanks for sharing!

Offshore software development India said...

Nice article, I was looking for these kind of information.

Please continue writing....


Android Application Development said...

Hello,great post. Information are pretty exciting and saved me huge amount of time which I have spend on something else instead of searching posts like this. I am waiting for more.

Andreas said...

Thanks for the great article. Saved me lot of time.
One question: Do you know how to exclude packages with the emma command you provided? The documentation only states out filters for usage with ant but I cannot make it work with the "emma" buckminster command? If you have an example, this would be great!

Flavio Donzé said...

hi Andreas

No I don't have an example but you can extend the "emma" command with the -P parameter where you can pass a properties file. Maybe this way you can exclude packages.


Flavio Donzé said...

To save stdout and stderr as files use the following emma command:

emma -l '/' -o '${WORKSPACE}/output/junit_result.xml' --xml '${WORKSPACE}/output/coverage_report.xml' --flatXML --stdout '${WORKSPACE}/output/stdout.txt' --stderr '${WORKSPACE}/output/stderr.txt'