jCoderZ Report

Tools like PMD, Checkstyle, FindBugs, Emma, and Cobertura deliver high-quality code-analysis features. The jCoderZ report (JcReport) tool reads the XML output of the code-analysis tools and creates a single report which combines all findings in one file. The final HTML report renders the source file as HTML pages and shows the findings directly in the lines, reported by the tools. The coverage information is displayed in a column at the left of the HTML page.

jcreport-marketecture.png

The report for the fawkeZ project can be found here. The findings section:

Findings: (2932)  error (5)  warning (2222)  info (705)  in 325 files

of the CruiseControl build result view provides another representation of the JcReport XML data.

Usage

The Ant task for the JcReport looks quite complex, but the structure is straight-forward and will hopefully become clear with the help of this introduction. As a sample you might check out the target in the build-report.xml of the fawkeZ project.

Note: All path settings described below are taken from the jCoderz JcReport example. If you want to use the report in your own project then you need to adapt all the path locations!

The output of the JcReport tool is a file called jcoderz-report.xml, a file called summary.xml, and a set of HTML files which contain the browsable version of the JcReport XML files.

<jcreport name="fawkez"
          dest="${base.dir}/build/doc/findings-report"
          wikibase="https://www.jcoderz.org/wiki/"
          webrcsbase="https://www.jcoderz.org/fawkez/browser/trunk"
          webrcssuffix=""
          packagebase="org.jcoderz"
          projectbase="${base.dir}"
          tempfolder="${base.dir}/build/jcreport"
          maxheap="128"
          debug="false">
    <classpath refid="jcreport.classpath"/>

    <!-- Reports Section -->
    <reports>   
        <report name="fawkez-test"
                level="test"
                sourcepath="${base.dir}/test/java"
                classpath="${build.dir}/classes"/>
        <report name="fawkez-prod"
                level="prod"
                sourcepath="${base.dir}/src/java"
                classpath="${build.dir}/classes"/>
    </reports>

    <!-- Tools Section -->
    <tools>
        <pmd config="${pmd.rules}"
             targetjdk="1.4"
             encoding="Cp1252">
            <classpath refid="pmd.classpath"/>
        </pmd>
        <cpd minimumtokens="100">
            <classpath refid="pmd.classpath"/>
        </cpd>
        <findbugs config="${findbugs.rules}"
                  maxheap="512"
                  effort="max"
                  debug="false"
                  warninglevel="low">
            <classpath refid="findbugs.classpath"/>
            <auxclasspath refid="findbugs.aux.classpath"/>
            <pluginlist refid="findbugs.plugins"/>
        </findbugs>
        <checkstyle config="${checkstyle.rules}"
                    maxheap="512"> 
            <classpath refid="checkstyle.classpath" />
        </checkstyle>
        <cobertura datafile="junit.ser"/>
            <classpath refid="cobertura.classpath" />
        </cobertura>
    </tools>

    <!-- Filters Section -->
    <filters>
        <filter file="${filter.rules}"/>
    </filters>
</jcreport>   

jcreport

The tag jcreport tag has the following attributes:

  • name: The name of the report ("fawkez").
  • dest: The folder where the report is stored ("${base.dir}/build/doc/findings-report").
  • wikibase: The project's Wiki URL ("/fawkez/wiki/").
  • webrcsbase: The base URL of the WebRcs view ("/fawkez/browser/trunk").
  • webrcssuffix: The suffix to append to the WebRcs URLs (E.g. "?root=project").
  • packagebase: The package prefix of the project ("org.jcoderz").
  • projectbase: The project's base directory ("${base.dir}").
  • tempfolder: A temporary folder ("${base.dir}/build/jcreport").
  • maxheap: The heap size in MB ("128").
  • debug: A debug mode flag ("false").
  • oldReportFile: Point this to the jcoderz-report.xml of the last build to get historic findings list.
  • cpus: The report will be executed in parallel using 'cpus' + 1 thread if possible.

The jcreport tag has the following child tags:

  • reports
  • tools
  • filters

reports

The reports tag can contain multiple report child tags. Each report tag defines a set of files that are checked by the code-analysis tool-chain. The files can be separated by level, which marks findings in the XML report jcoderz-report.xml with a level attribute. This attribute can later be used for filtering findings from test code for example.

<report name="fawkez-prod"
        level="prod"
        sourcepath="${base.dir}/src/java"
        classpath="${build.dir}/classes"/>

The tag name is the name of the file collection, level is the name of the level (see ReportLevel for the possible values), sourcepath is the path to the source files of this collection, and classpath is the classpath that contain the classes for this file collection.

tools

The tools tag has the following child tags:

  • pmd
  • cpd
  • findbugs
  • checkstyle
  • cobertura
  • emma

All tools have the attribute maxheap in common. The tools are forked by the JcReport because the tools have different requirements in terms of heap size. Therefore it is possible to set the maximum heap size of all tools independently.

All tools have a child tag classpath in common which defines the classpath for the single tool. Because the tools are forked by the JcReport in the background the classpath must be the same as when launching the tools separately.

Some tools have a debug attribute to turn on debug information. The output is dependent on what the tool provides in terms of debugging information.

pmd

The attributes of the pmd tag are defined by the PMD command line tool:

<pmd config="${pmd.rules}"
     targetjdk="1.4"
     encoding="Cp1252">
    <classpath refid="pmd.classpath"/>
</pmd>

The config attribute defines the PMD configuration file. The targetjdk defines the JDK version of the source files, and the encoding attribute defines the source file encoding.

cpd

The Copy Paste Detector (CPD) is part of the PMD project and can be used to detect copied & pasted code. The attributes of the cpd tag are defined by the CPD command line tool:

<cpd minimumtokens="100">
    <classpath refid="pmd.classpath"/>
</cpd>

The tag minimumtokens defines the minimum number of tokens in an analyzed code sequence when the code blocks are considered to be copied.

findbugs

The attributes of the findbugs tag are defined by the FindBugs command line tool:

<findbugs config="${findbugs.rules}"
          maxheap="512"
          effort="max"
          debug="false"
          warninglevel="low">
    <classpath refid="findbugs.classpath"/>
    <auxclasspath refid="findbugs.aux.classpath"/>
    <pluginlist refid="findbugs.plugins"/>
</findbugs>

The config attribute points to the place where the FindBugs config file can be found. The FindBugs config file is different from the rest of the config files as it contains an exclude list. In FindBugs all checkers that FindBugs supports are turned on per default. This file allows to turn off rules so that FindBugs does not try to detect code that violates these rules. The effort tag defines how hard FindBugs tries to find problems in the code. The warninglevel attribute declares which bug priorities FindBugs reports. The warninglevel is related to the command line switches -low, -medium, and -high.

checkstyle

The attributes of the checkstyle tag are defined by the Checkstyle command line tool:

<checkstyle config="${checkstyle.rules}"
            maxheap="512"> 
    <classpath refid="checkstyle.classpath" />
</checkstyle>

The config attribute defines the Checkstyle configuration file.

cobertura

The attributes of the cobertura tag are defined by the Cobertura command line tool:

<cobertura datafile="junit.ser"/>
    <classpath refid="cobertura.classpath" />
</cobertura>

The cobertura tag has only one attribute, which defines the datafile into which the coverage information has been written into.

emma

Please note that only one of cobertura or emma can be set.

To include the result of an emma analysis the following line should be added as tool:

<emma datafile="${build.dir}/full-coverage.es"/>

Emma reports the coverage different than cobertura. Emma does not count the number of times a line is was touched, it checks if a branch/block of code was executed or not. Since one line of java code can hold several branches but the precision we use for the report is one line, we percent the coverage as percentage of line coverage. So if a line holds two branches but only one was covered a 50 is displayed representing 50%. If a line was covered in all its potential branches a 100 is displayed. Check out the emma web site for more details on this.

For emma}} we do not use the emma xml as input, because it does not contain the detail of information needed. Use the (probably merged) binary {{{*.es file that should contain all data.

filters

The filters tag can contain an arbitrary set of filter tags that define a list of XSL filter files to filter out findings from the JcReport XML file.

<filter file="${filter.rules}"/>

The filter step runs on the jcoderz-report.xml file prior to HTML rendering.

Rulesets

The ruleset files in fawkeZ are declared like this:

<property name="pmd.rules" value="${base.dir}/config/jcoderz-pmd.xml"/>
<property name="checkstyle.rules" value="${base.dir}/config/jcoderz-checkstyle.xml" />
<property name="findbugs.rules" value="${base.dir}/config/jcoderz-findbugs.xml" />
<property name="filter.rules" value="${base.dir}/config/jcoderz-report-filter.xsl" />

Classpath

As mentioned above the classpath settings for the different tools need to be the same as when running the tools from the command line. Here is an example of the classpath settings as it is defined for the jcoderz.org JcReport:

<path id="jcreport.classpath">
    <pathelement path="${base.dir}/build/classes"/>
    <fileset dir="${base.dir}/lib">
        <include name="default/jaxb/*.jar"/>
        <include name="default/chart2d/*.jar"/>
    </fileset>
</path>
<!-- This classpath is used by the checkstyle process -->   
<path id="checkstyle.classpath">
    <fileset dir="${base.dir}/lib">
        <include name="default/antlr/*.jar"/>
        <include name="default/checkstyle/*.jar"/>
        <include name="default/commons-beanutils/*.jar"/>
        <include name="default/commons-cli/*.jar"/>
        <include name="default/commons-logging/*.jar"/>
    </fileset>
</path>
<!-- This classpath is used by the pmd and cpd process -->   
<path id="pmd.classpath">
    <fileset dir="${base.dir}/lib">
        <include name="default/pmd/*.jar"/>
        <include name="default/jaxen/*.jar"/>
        <include name="default/oro/*.jar"/>
    </fileset>
</path>
<!-- This classpath is used by the findbugs process -->   
<path id="findbugs.classpath">
    <fileset dir="${base.dir}/lib">
        <include name="default/findbugs/*.jar"/>
        <include name="default/dom4j/*.jar"/>
        <include name="default/jaxen/*.jar"/>
        <exclude name="**/coreplugin.jar"/>
    </fileset>
</path>

<!-- This classpath defines the findbugs plugins -->   
<path id="findbugs.plugins">
    <path location="${base.dir}/lib/default/findbugs/coreplugin.jar"/>
</path>

<!-- This is the auxiliary classpath used by findbugs -->   
<path id="findbugs.aux.classpath">
    <path location="${base.dir}/build/classes"/>
    <fileset dir="${base.dir}/lib">
        <include name="default/chart2d/*.jar"/>
        <include name="default/jaxb/*.jar"/>
        <include name="default/commons-httpclient/*.jar"/>
        <include name="default/commons-cli/*.jar"/>
        <include name="default/commons-pool/*.jar"/>
        <include name="default/checkstyle/*.jar"/>
        <include name="default/fop/*.jar"/>
        <include name="default/jtidy/*.jar"/>
        <include name="default/batik-1.5-fop/*.jar"/>
        <include name="default/velocity/*.jar"/>
        <include name="default/jivesoftware/*.jar"/>
        <include name="default/geronimo-spec/*.jar"/>
        <include name="default/cobertura/*.jar"/>
        <include name="default/ant/*.jar"/>
        <include name="default/antlr/*.jar"/>
        <include name="default/xercesImpl/*.jar"/>
        <include name="default/xalan/*.jar"/>
        <include name="eclipse/*.jar"/>
    </fileset>
</path>

Taskdefs

This is the Ant taskdef definition for the jcoderz.org JcReport:

<taskdef name="jcreport"
         classname="org.jcoderz.phoenix.report.JcReportAntTask">
    <classpath refid="jcreport.classpath" />
</taskdef>