Serenity Plugin

Skip to end of metadata
Go to start of metadata

Plugin Information

Plugin ID serenity Changes In Latest Release
Since Latest Release
Latest Release
Latest Release Date
Required Core
1.0 (archives)
Dec 08, 2013
Source Code
Issue Tracking
Open Issues
Michael Couck (id: michael.couck)
Usage Installations 2014-Nov 129
2014-Dec 127
2015-Jan 127
2015-Feb 133
2015-Mar 138
2015-Apr 126
2015-May 130
2015-Jun 138
2015-Jul 153
2015-Aug 153
2015-Sep 157
2015-Oct 166

Serenity is a Java code coverage, complexity and dependency library that uses dynamic instrumentation, with a friendly Hudson ui.
Configuring Serenity with Jenkins/Hudson is very simple, four steps. For feature requests please feel free to mail me at michael dot couck at gmail dot com.

1) Download the Serenity and unpack it in the same directory as your build.xml or pom.xml.
2) Add the properties for which packages you want to generate code metrics for, and the adapters that you would like to use by adding this to the build.xml for Ant builds:

<!-- Serenity system properties. -->
<sysproperty key="included.packages" value="" />
<sysproperty key="included.adapters" value="coverage,complexity,dependency" />

And by adding this to the pom.xml for Maven builds:


3) Add the agent to the command line for Ant like this:

<!-- Serenity JVM command line. -->
<jvmarg line="-javaagent:serenity/serenity.jar" />

And for Maven like this:

<argLine>-javaagent:serenity/serenity.jar -Xms512m -Xmx1024m ${included.packages} ${included.adapters}</argLine>

4) In the configuration page for the project in Hudson check the Serenity box at the bottom.

And that is it, run as normal.

For a multi-Maven project the above steps need to be followed for each module. The JavaAgent configuration can be relative to the directory where Maven will build the module for example in the ikube project the Serenity folder is in the top level project folder and the references to the JavaAgent are like ../../serenity/serenity.jar. For all the modules, so there only need be one installation of the Serenity Jar. However for each module the output will be in the 'serenity' folder in the module folder. After the build the data collected for each module is accumulated and aggregated and published to the build folder for Hudson for the reports.

System properties that are available and can be set are:

1) included.packages - the package names that are to be collected, semi-colon separated list(mandatory)
2) included.adapters - the class adapters that will generate the collection data for the classes, semi-colon separated list(mandatory)
3) write.classes - whether the modified classes are to be written to the file system for later inspection, true or false(optional)
4) clean.classes - whether to delete the old class files on the file system before writing the new ones, true or false(optional)
5) included.jars - jar files that are to be included in the accumulation, for source files if the source is not added to the build jars during the build(optional)

Full example configuration of Serenity for an Ant build:

To enable the JavaAgent the Ant build script needs to be modified to include the agent as in the following:

<jvmarg line="-javaagent:serenity/serenity.jar" />

Below is the build.xml fragment from the FindBugs project running Serenity as an example.

<target name="test" depends="junittests,jars">
	<echo>Running JUnit test cases for FindBugs...</echo>
	<junit fork="true" printsummary="true" showoutput="true" filtertrace="true" forkmode="once">
		<!-- Serenity system properties. -->
		<sysproperty key="included.packages" value="edu.umd.cs.findbugs" />
		<sysproperty key="included.adapters" value="coverage,complexity,dependency" />

                <!-- Serenity JVM command line. -->
		<jvmarg line="-javaagent:serenity/serenity.jar" />

		<formatter type="xml" />
		<classpath refid="tools.classpath" />
			<pathelement path="${junitclasses.dir}" />
		<!-- And run the tests. -->
		<batchtest todir="build/junit" haltonerror="false" haltonfailure="false">
			<fileset dir="${junitsrc.dir}">
				<include name="**/*Test*.java" />

Full example configuration of Serenity for a Maven build:

As in the Ant configuration there are system parameters that can be set, and those that need to be set. Below is a fragment from a pom configured to run Serenity during the test phase of Maven:


				<argLine>-javaagent:serenity/serenity.jar -Xms512m -Xmx1024m ${included.packages} ${included.adapters}</argLine>

As can be seen from the above, properties are defined for the Serenity properties and used in the command line for the Surefire plugin.

Additional technical details, configuration details and trouble shooting

Serenity runs as a JavaAgent, as such the byte code is modified in memory. Serenity will generate statistics on coverage, complexity and dependency for the project depending on the adapters defined in the system property 'included.adapters'. The instrumented classes can be written to the file system to be validated visually by setting a system property 'write.classes'. The class files will be written to the 'serenity' folder.

The JUnit task in both Ant and Maven needs to be in forked mode, and typically with the option 'once' set to true. Starting a new JVM for every test will be very time consuming and data will be overwritten with each JVM, i.e. the results are undefined.

The command line for Ant and Maven must have no spaces or page breaks, i.e. one long command. The JVM doesn't like page breaks and complains bitterly about the agent not starting etc.

If no adapters are added, or the names for the adapters are wrongly spelled then no metrics will be generated for the classes. Generally all the adapters are added. The coverage adapter is the most sought after, and incidentally the most expensive for performance, but the others are not very expensive at all as it turns out so there is no harm in adding them too.

In the plugin, viewing of the source and the covered lines is desirable. To include source the source must be in the jars that are generated and are on the classpath, not in folders. Alternatively the source can be in the 'indluded.jars' property. The jars that are specified here must then contain not only the source but the class files too.

Serenity will maintain all the data in memory until the JVM for the unit tests shuts down. As such, depending on the size of the project, the memory needs to be set appropriately. This can be set on the command line for the Maven build and for Ant in the 'jvmarg' tag as in the following:

<argLine>-javaagent:serenity/serenity.jar -Xms512m -Xmx1024m ${included.packages} ${included.adapters}</argLine>
<jvmarg value="-XX:PermSize=256m" />
<jvmarg value="-XX:MaxPermSize=512m" />
<jvmarg value="-Xms768m" />
<jvmarg value="-Xmx1024m" />

Typically performance for the tests will be p = p * 3 with the coverage added. Generally however unit tests are fast and not performance sensitive.

There are no publicly available projects that are using Serenity unfortunately, so there are no full working examples that you can have a look at, however if you get stuck feel free to give me a shout at michael.couck at gmail dot com.


1) When classes are enhanced by Spring for example the tests will behave very badly indeed. Enhanced code getting enhanced again seems to have unpredictable side effects. In this case it is best to add excluded packages to the configuration so the classes that are AOP enhanced will not be enhanced again by Serenity, or in fact it is the other way around. Serenity will enhance the classes then they will be enhanced by Spring/AspectJ, depending on the agent order I guess. Either way it does not work. In the case of the test project(Ikube) the database package was excluded as this package gets enhanced by Spring.


1) 12.05.10 - Added slave support, finally.

2) Updated the accumulation logic to not include the specifically excluded classes.

3) Sorted out the JavaScript tree for all browsers.

This is a screen shot of the Serenity trend result and the report in Jenkins.


plugin-report plugin-report Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Add Comment