Index
User Guide
FAQ


Clover Website



 

Clover User Guide

Contents:

Introduction

This user guide covers the basics of getting up and running with Clover. It covers basic integration, configuration and reporting scenarios. It assumes that the user is familiar with the Jakarta Ant build tool, and with modifying Ant build files. For help with Ant, see http://jakarta.apache.org/ant/manual/index.html. For Clover troubleshooting information, see the FAQ.

Clover Quick Start Guide

Clover works by instrumenting a copy of your java source before compilation. Because Clover is tightly integrated with Ant, modifying a build file to use Clover is straightforward. Because of the flexibility of Ant, the technique described here is only one of many possible ways to integrate Clover with Ant.

  1. ensure you are using a recent version of Ant (v1.4.1 or greater)
  2. if you haven't done so already, download Clover. Unpack the Clover archive to a directory.
  3. copy <CLOVER_HOME>/lib/clover.jar into <ANT_HOME>/lib
  4. edit build.xml for your project:
    1. add a property that tells Clover a path to write coverage data (Clover will create and write to this file during compile-time, and write coverage data along side it at runtime):
      <property name="clover.initstring" location="/tmp/mycoverage.db"/>
    2. add a target to switch on Clover:
      <target name="with.clover">

      <property name="build.compiler"
      value="org.apache.tools.ant.taskdefs.CloverCompilerAdapter"/>
      </target>
    3. add a target to run a clover report:
      add a path element that holds the classpath for Clover (edit the path to point to the Clover jars on your filesystem):
      <path id="clover.classpath">
      <pathelement path="<CLOVER_HOME>/lib/clover.jar"/>
      <pathelement path="<CLOVER_HOME>/lib/velocity.jar"/> <-- only needed if you are using html reporter --> </path>
      to launch the Swing viewer, use:

      <target name="clover.report">
      <java classname="com.cortexeb.tools.clover.reporters.jfc.Viewer" fork="yes">
      <arg line="${clover.initstring}"/>
      <classpath refid="clover.classpath"/>
      </java>
      </target>
      - OR - for html reporting, use (change the outputdir to a path where Clover should put the generated html):

      <target name="clover.report">
      <java classname="com.cortexeb.tools.clover.reporters.html.HtmlReporter" fork="true">
      <arg line="--outputdir /tmp/clover_html --showSrc --initstring ${clover.initstring} --title 'My Project'"/>
      <classpath refid="clover.classpath"/>
      </java>
      </target>
      - OR - for xml reporting, use (change the outfile to a file where Clover should write the xml file):

      <target name="clover.report">
      <java classname="com.cortexeb.tools.clover.reporters.xml.XmlReporter" fork="true">
      <arg line="--outfile /tmp/coverage.xml --initstring ${clover.initstring} --title 'My Project'"/>
      <classpath refid="clover.classpath"/>
      </java>
      </target>
      - OR - for simple emacs-style reporting to the console, try:

      <target name="clover.report">
      <java classname="com.cortexeb.tools.clover.reporters.emacs.EmacsCloverReporter">
      <arg line="--level method --initstring ${clover.initstring} --title 'My Project'"/>
      <classpath refid="clover.classpath"/>
      </java>
      </target>
  5. Save your build.xml
  6. Now you can build your project with Clover turned on by adding the "with.clover" target to the list of targets to execute. For example (if your compile target is named 'build' and your unit test target is named 'test'):
    ant with.clover build test
    note: if when you run this command problems occur, chances are clover is not in the runtime classpath. See the section below on Clover and classpaths.
  7. To generate a Clover coverage report:
    ant clover.report
Clover and classpaths

In your javac task, if you have set the attribute includeAntRuntime="no", you will need to add the Clover jar to the compilation classpath. The easiest way to achieve this is to add the Clover classpath reference to javac tasks, like this:

     <javac ...>

...
<classpath refid="clover.classpath"/>
</javac>

Similarly, clover.jar will need to be in the runtime classpath whenever you run Clovered code. This is quite often as simple as adding a classpath reference (like the one above) to execution tasks (like <java> or <junit>). For other projects, particularly Hosted Applications, you must ensure that clover.jar is deployed along with your clovered code.

Compile-time properties

Clover's instrumentation process is controlled by the set of Ant properties described below. Note that all but one of these properties are optional - the only required property is clover.initstring.
Property:clover.initstring
Required?YES
Values:valid & writable file path
Description: The string used to initialise and access the Clover coverage database. You must set this to a file that Clover can create and write to at compile-time. Clover will also create and write to a series of coverage data files during runtime -these will be created in the parent directory of the file specified above. The specified path must resolve to the same location at both compile-time and runtime. For this reason, using an absolute path is the safest option.
 
Property:clover.enable
Required?NO
Values:true,false
Default:true
Description: Setting this property to false disables Clover. This is convenient if you want to turn Clover on and off without using the build.compiler property
 
Property:clover.compiler
Required?NO
Values:see Ant Javac doc
Default:Ant default
Description: The compiler to delegate to once instrumentation is complete. If you need to specify a non-default compiler for the javac task (normally done by setting the build.compiler Ant property) then you can use clover.compiler to achieve the this.
 
Property:clover.preserve
Required?NO
Values:true,false
Default:false
Description: Setting this property to true tells Clover to preserve the instrumented source. This is useful primarily for debugging Clover. The default is false - the instrumented source is deleted after compilation.
 
Property:clover.tmpdir
Required?NO
Values:A valid and writable directory path
Default:Obtained using java.io.File.createTempFile()
Description: The directory that Clover will use to write an instrumented copy of your source code.
 
Property:clover.excludes, clover.includes
Required?NO
Values:see Ant PatternSet doc
Default:See below
Description: A comma or space separated list of Ant patternset matching expressions that determines which source files get included or excluded at the Clover instrumentation step. Note that files that are excluded are still compiled - just not instrumented by Clover.

If neither property is set, all files specified in the javac task will be processed by Clover.

If only clover.includes is set, files matching one of the specified include patterns will be instrumented.

If only clover.excludes is set, all files specified in the javac task will be instrumented, except files matching any of the specified excludes patterns.

If both properties are set, excludes override includes.

 
Property:clover.useclass.includes
Required?NO
Values:see Ant PatternSet doc
Default:empty
Description: A comma or space separated list of Ant patternset matching expressions that determines which source files get instrumented using the "inner class" approach. This is useful for classes that are interface-sensitive (like CMP beans) and for resolving (rare) circular classloading problems.
 
Property:clover.flushpolicy
Required?NO
Values:directed, interval
Default:directed
Description: This property controls how Clover flushes coverage data to disk during a coverage run. Regardless of this setting, Clover will automatically attempt to register a shutdown hook that will flush coverage data on JVM shutdown. See Flushing at JVM shutdown below.

When the value of this property is directed, Clover will only insert code to flush coverage data when explicitly directed to by the occurance of a Clover FLUSH directive in the source. See Clover source level directives.

When the value of this property is interval, Clover will flush at most every n milliseconds, where n is the value of the clover.flushpolicy.interval property.

Note: Depending on your application, small values of n can have a significant performance impact.

Note: Clover will still insert flush code when a FLUSH directive is encountered in the source.

Flushing at JVM shutdown

Clover automatically attempts to add a shutdown hook that will flush coverage data on JVM shutdown. On pre-1.3 JVMs this will have no effect, and you must use one of the flushing policies above. Note also that some server containers impose security settings that prevent the registration of shutdown hooks. See Clover and Hosted Applications.

 
Clover source-level directives

Clover supports a number of directives that you can use in your source to control instrumentation. Directives can be on a line by themselves, or part of any valid single or multi-line java comment. The supported directives are:

///CLOVER:ON
///CLOVER:OFF

Switch Clover instrumentation on/off. This might be useful if you don't want Clover to instrument a section of code for whatever reason. Note that the scope of this directive is the current file only.

///CLOVER:FLUSH

Clover will insert code to flush coverage data to disk. The flush code will be inserted as soon as possible after the directive.

///CLOVER:USECLASS

Clover will use a static holder class rather than a static member variable to support instrumentation for the current file. The directive must occur before the first top level class declaration in the file. This directive is useful when you don't want Clover to change the public interface of your class (in EJB compilation for example).

Clover and Hosted Applications

We have successfully used Clover with applications hosted on serveral applications servers, including JBoss, Weblogic 5.1, and others. When using Clover with hosted apps, the following points should be considered:
  • At the moment, Clover needs read and write access to the same filesystem at compile-time and runtime. This means that where-ever clovered code is loaded and executed, it must be able to access the file specified at compile-time in the clover.initstring property. It must also be able to create and files in the same directory. Some app servers block access to the file system for hosted applications. You may need to change the server security settings to loosen this restriction.
  • The Clover runtime jar must be deployed alongside any clovered code.
  • Clover will attempt to register a JVM shutdown hook to flush coverage data when the JVM shuts down. Some app servers (e.g. Weblogic 5.1) block access to this facility by default. To workaround this, you can either use another clover.flushpolicy, or loosen the server server security settings to allow registration of shutdown hooks.

Using the Reporters

Three reporters currently exist for Clover.

Swing Viewer

The Swing Coverage viewer supports interactive source level coverage browsing. To run it from Ant, use something like:
<target name="clover.report">
  <java classname="com.cortexeb.tools.clover.reporters.jfc.Viewer" fork="yes">
   <arg line="${clover.initstring}"/>
   <classpath refid="clover.classpath"/>
  </java>
</target>
Emacs Reporter

The Emacs Reporter can be used for basic coverage reporting to the console. To run it from Ant, use something like:
<target name="clover.report">
  <java classname="com.cortexeb.tools.clover.reporters.emacs.EmacsCloverReporter">
   <arg line="--level method --initstring ${clover.initstring} --title 'My Project'"/>
   <classpath refid="clover.classpath"/>
  </java>
</target>
Html Reporter

The Html Reporter produces html-based reports of your coverage data. The easiest way to run the Html Reporter is by creating an appropriate Ant target in your build file:
<target name="clover.report">
  <java classname="com.cortexeb.tools.clover.reporters.html.HtmlReporter" fork="true">
   <arg line="--outputdir /tmp/clover_html --initstring ${clover.initstring} --title 'My Project'"/>
   <classpath refid="clover.classpath"/>
  </java>
</target>
Parameters supported by the Html reporter:
-o, --outputdir <dir>output directory for generated html. Will be created if it doesn't exist.
-i, --initstring <string>The clover database to report on.
-t, --title <string>(optional)  title to put on the top of report.
-bw(optional)  Don't color syntax-hilight source - smaller html output.
-e, --showempty(optional)  show classes/packages in the report even if they don't have any statements, methods or conditionals. default is false
-n, --nocache(optional)  insert no-cache browser directives in html output.
-h, --hidesrc(optional)  don't render source code.
-l, --ignore <string>(optional)  comma or space separated list of blocks to ignore when generating coverage reports. Most useful one is "catch". Valid values are "static", "instance", "constructor", "method", "switch", "while", "do", "for", "if", "else", "try", "catch", "finally", "sync"
-c, --orderby <string>(optional)  comparator to use when listing packages and classes. Valid values are "alpha" - alphabetic, "desc" - coverage descending, "asc" - coverage ascending. default is "asc".
-d, --debug (optional)  switch logging to debug level
-v, --verbose (optional)  switch logging to verbose level


XML Reporter

The Xml Reporter produces summary XML reports of your coverage data. To run it from Ant, use something like:
<target name="clover.report">
  <java classname="com.cortexeb.tools.clover.reporters.xml.XMLReporter" fork="true">
   <arg line="--outfile coverage.xml --initstring ${clover.initstring} --title 'My Project'"/>
   <classpath refid="clover.classpath"/>
  </java>
</target>
Parameters supported by the Html reporter:
-o, --outfile <dir>output file for XML
-i, --initstring <string>The clover database to report on.
-t, --title <string>(optional)  title to put on the top of report.
-d, --debug (optional)  switch logging to debug level
-v, --verbose (optional)  switch logging to verbose level
 

© 2002 Cortex eBusiness. All rights reserved.
Java is a trademark of Sun Microsystems, Inc