Contents


Integrating FindBugs, CheckStyle and Cobertura with Rational Team Concert build system

Comments

In continuous integration software development methodology, each new functionality is developed individually and then integrated together later. While going through this process, each developer needs to be thorough in reviewing code on the static analysis front, and report back or track it in a system like IBM Rational Team Concert™. The coding language Java has more than 400 standard static analysis bug types. Ensuring that each bug is addressed during the review process and noting each defect can be very tedious.

Integrating FindBugs, CheckStyle, and Unit Test Coverage Check (Cobertura) with Rational Team Concert reduces the reviewing process for delivered code within a project. Some developers are not aware of coding best practices. This can lead to performance issues such as a memory leak or poor CPU utilization. These types of problem are auto-detected by the tool integration with Rational Team Concert, which creates defects for such issues.

This integration improves the quality of code; it's good for project and its end users.

Overall design and description

To understand implementation details, look at Rational Team Concert as a base system. Considering Rational Team Concert to be a base system means viewing the build engine, source repository, and ticketing system as a single unit. As Figures 1 and 2 below show, Rational Team Concert provides the ability to request a build for configured steps over source repository through build engine component. Those configured build steps are the place where we want to add scripts to run the quality assurance tools. We can run these tools either in sequential mode or in parallel mode. Because these tools are independent of each other, I prefer to run them in parallel mode. In the case of Cobertura, it works with unit testing that is done during the build so it needs to run at the same time as unit testing.

Figure 1. Integration block diagram
The tools are integrated with Rational Team Concert
The tools are integrated with Rational Team Concert
Figure 2. Tool integration flow chart
How the control flows in this quality tools integration with Rational Team Concert.
How the control flows in this quality tools integration with Rational Team Concert.

Individual tool wise implementation and integration details

FindBugs

FindBugs is an open source program created by Bill Pugh and David Howemeyer that looks for bugs in Java code. It uses static analysis to identify hundreds of different potential types of errors in Java programs. Potential errors are classified in four ranks: "scariest", "scary", "troubling", and "of concern". We suggest this be run in the install phase of maven build.

How to integrate FindBugs with Rational Team Concert

  1. Add a FindBugs tool entry in the build file of the project that will run FindBugs during the project build. Listing 1 contains the build XML part which will trigger FindBugs and generate the output file with an HTML report.
Listing 1. FindBug during build with line by line explanation
  <tasks>
1    <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.plugin.classpath" />
     <mkdir dir="${basedir}/target" />
2    <property name="findbugs.home" value="${env.FINDBUGS_HOME}" />
3    <path id="findbugs.lib" >
       <fileset dir="${findbugs.home}/lib" >
         <include name="**/*.jar" />
       </fileset>
     </path>
4    <property name="proj.file" value="project.fbp" />
5    <property name="current.scan" value="target/scan-out.xml" />
6    <property name="temp.db" value="target/temp-db.xml" />
7    <property name="report.file" value="target/findbugs-report.html" />

     <!-- scan the target code -->
8    <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
       <classpath refid="findbugs.lib" />
     </taskdef>
9    <findbugs home="${findbugs.home}" 
        projectFile="${proj.file}"
        excludeFilter="excludes.xml"
        includeFilter="includes.xml"
        output="xml" 
        outputFile="${current.scan}" />

     <!-- finally generate HTML report off the temporary db -->
10   <taskdef name="convertXmlToText" classname=
        "edu.umd.cs.findbugs.anttask.ConvertXmlToTextTask">
       <classpath refid="findbugs.lib" />
     </taskdef>
11   <convertXmlToText home="${findbugs.home}" 
       input="${temp.db}" 
       output="${report.file}" 
       format="html:fancy-hist.xsl" 
       jvmargs="-Djavax.xml.transform.TransformerFactory=
        org.apache.xalan.processor.TransformerFactoryImpl" />
  </tasks>

Let's look more closely at Listing 1.

  • Line 1: Defines the task definition resource which refers to the class path from maven: maven.plugin.classpath.
  • Line 2: Defines FindBugs home, which points to the executable and library of FindBugs.
  • Line 3: Includes all .jar files from the FindBugs home path. They will be used in later processing.
  • Line 4: Defines the project file location in which all project-related info is to be placed. There is an example of this in the next section.
  • Line 5: Defines the output XML file location as scan-out.xml.
  • Line 6: Defines the database file which can be use to maintain bug history.
  • Line 7: Defines the report file location.
  • Line 8: FindBugs task definition (declaration).
  • Line 9: FindBugs tool execution.
  • Line 10: Report task definition (declaration).
  • Line 11: Report generation. It converts the data from XML to HTML.

Project file (project.fbp) should contain the info from Listing 2. It lists all class folders to be scanned, dependent .jar files used to compile those classes, and a source directory of the classes.

Listing 2. Example of project.fbp
<Project projectName="MyProject">
  <Jar>../MyProject/target/classes</Jar>
  <AuxClasspathEntry>../MyProject/lib/servlet-api-2.5.jar</AuxClasspathEntry>
  <SrcDir>../MyProject/src</SrcDir>
</Project>
  1. The file scan-out.xml contains the output of FindBug tool that ran on the project. Listing 3 is an example of that file.
Listing 3. Example of scan-out.xml
<BugInstance type="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" priority="2" abbrev="UrF" 
category="STYLE">
  <Class classname="com.ibm.myproject.task.Process">
    <SourceLine classname="com.ibm.myproject.task.Process" start="21" end="57" 
    sourcefile="Process.java" sourcepath="com/ibm/myproject/task/Process.java"/>
  </Class>
  <Field classname="com.ibm.myproject.task.Process" name="conn" signature=
    "Lcom/com/ibm/myproject/task/Connection;" isStatic="false">
    <SourceLine classname="com.ibm.myproject.task.Process" sourcefile="MyHTTP.java" 
    sourcepath="com/ibm/myproject/task/Process.java"/>
  </Field>
  <SourceLine classname="com.ibm.myproject.task.Process" start="25" end="25" 
    startBytecode="11" endBytecode="11" sourcefile="Process.java" sourcepath=
    "com/ibm/myproject/task/Process.java"/>
</BugInstance>
  1. Create a text file called BugSet.txt that contains a single line for each bug reported in scan-out.xml. Use XSL or scripting to do this.
  2. Transform each bug from the BugSet text file into a Rational Team Concert WorkItem JSON format and submit it to Rational Team Concert using the auto ticketing function, explained below.

CheckStyle

CheckStyle is a static code analysis tool used in software development to verify whether Java source code complies with coding rules.

How to integrate CheckStyle with Rational Team Concert

  1. Add a CheckStyle tool entry in the build file of a project that will run CheckStyle during a project build. Listing 4 is the build XML section which triggers CheckStyle and generates the output file and HTML report.
Listing 4. CheckStyle during build with line by line explanation
 <tasks>
1  <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref=
    "maven.plugin.classpath" />
    <mkdir dir="${basedir}/target" />
	
2  <property name="checkstyle.home" value="${env.CHECKSTYLE_HOME}" />
3  <path id="checkstyle.lib" >
     <fileset dir="${checkstyle.home}" >
       <include name="**/*.jar" />
     </fileset>
   </path>
									
4  <property name="config_loc" value="${env.BUILD_SCRIPTS}/common/checkstyle" /> 
    <!-- this is for Eclipse-CS to be able to find excludes.xml -->
5  <property name="target.dir" value="${basedir}/target" />
6  <property name="scan.xml" value="${target.dir}/scan.xml" />
									
   <taskdef resource="checkstyletask.properties" classpathref="checkstyle.lib"/>
	
   <!-- Task: Scan	-->
7  <checkstyle config="${config_loc}/myproject-checkStyle-config.xml" classpathref=
    "checkstyle.lib" failOnViolation="false">
     <fileset dir="${env.BUILD_HOME}/myproject/src" includes="**/*.java" />	
     <formatter type="xml" toFile="${scan.xml}" />
   </checkstyle>
 </tasks>

Let's look more closely at Listing 4.

  • Line 1: Defines the task definition resource which refers to the class path from maven: maven.plugin.classpath.
  • Line 2: Defines the CheckStyle home which points to the executable and library of CheckStyle.
  • Line 3: Includes all .jar files from CheckStyle home path that will be used in later processing.
  • Line 4: Defines the config location where we put config files like excludes.xml.
  • Line 5: Defines the target directory where all output will be generated.
  • Line 6: Defines the output XML file location. In this example, it is scan.xml.
  • Line 7: Performs the actual scan located under the defined source folder. It selects only Java files. The output will be generated in XML format. In this example, it will go in scan.xml.
  1. In the case of the checkstyle scan output, it generates detailed output so that the extract XSL transformation can be used. A sample XSL file is shown in Listing 5. The sample generates a .txt file that contains list of bugs.
Listing 5. Sample XSL file
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="ISO-8859-1" indent="no" />
<xsl:template match="/">
  <!-- we loop over all the files reported -->
  <xsl:for-each select="checkstyle/file">
    <xsl:variable name="fname" select="@name" />
    <!-- we then loop over all the errors within the file -->
    <xsl:for-each select="error">
      <xsl:variable name="errtype">
        <xsl:choose>
          <xsl:when test=
            "@source='com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck'">
            Javadoc</xsl:when>
          <xsl:when test=
            "@source='com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocStyleCheck'">
            Javadoc</xsl:when>
          <xsl:otherwise>Other</xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      <xsl:value-of select="$errtype" /><xsl:text> problem(s) in 
      </xsl:text><xsl:value-of select="$fname"/><xsl:text>
</xsl:text>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>
  1. Transform each bug from the DefectSet text file into the Rational Team Concert WorkItem JSON format and submit it to Rational Team Concert using the auto ticketing function, explained below.

Cobertura

Cobertura is an open source tool for measuring code coverage with the help of code testing. It does so by instrumenting the byte code. This tool is based on jcoverage and helps programmers measure the effectiveness of their tests and the amount of code that is reached by the test.

Integrate Cobertura with Rational Team Concert?

Add a Cobertura tool entry in the build file of the project that will run Cobertura during the project build. Listing 6 is the build XML section which triggers Cobertura and generates the output file with the HTML report.

Listing 6. Cobertura during build
 <tasks>
1  <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref=
    "maven.plugin.classpath" />
   <mkdir dir="${project.build.directory}/coverage"/>
2  <taskdef name="cobertura-report" classname="net.sourceforge.cobertura.ant.ReportTask" 
    classpathref="maven.compile.classpath"/>
3  <cobertura-report datafile="${project.build.directory}/cobertura.ser" format="xml"
     destdir="${project.build.directory}/coverage/xml">
     <fileset dir="${basedir}/../myproject/app1/src">
       <include name="**/*.java" />
     </fileset>
   </cobertura-report>
 </tasks>

Let's look more closely at Listing 6.

  • Line 1: Defines the task definition resource which refers to class path from maven: maven.plugin.classpath.
  • Line 2: Defines the Cobertura task.
  • Line 3: The Cobertura XML report generator builds based on the cobertura.ser file in which instrumentation data is stored.

Rational Team Concert auto ticketing

  1. Create a JSON for every line in the text file, which will be for each bug reported. Listing 7 is the JSON template.
Listing 7. Rational Team Concert defect JSON
{
  "dc:title":"[Static Analysis] @BUGSUBJ@",
  "dc:description":"@BUGSUBJ@<br\/><br\/>This problem was found in build: 
  @BUILDID@.<br\/>
  <br\/>Please see the FindBugs report attached to the above build for more 
  details;<br\/>
  1. in Rational Team Concert client, go to Team Artifacts > My Project > 
  Builds<br\/>
  2. find the build definition: @BLDDEFN@, and double click it<br\/>
  3. in the Builds view that opens, find a build with the 'Label' value matching the 
  build# above, and double click it<br\/>
  4. in the Build Result that opens, go to the 'Downloads' tab, and double click the 
  'logs' in the list<br\/>
  5. now your browser should come up, and you just click the 
  findbugs-myproject.html<br\/>"
	
  "rtc_cm:plannedFor":
  {
    "_comment":"Specifies 'Development' as planned-for for the ticket",
    "rdf:resource":"https://myjazzrtc.ibm.com:9000/ccm/oslc/iterations/
    _gMAnkOlIEeKwsc_eM5wLCA"
  },
  "rtc_cm:ownedBy":
  {
    "_comment":"Specifies 'Developer1' (=_0k3H0MheEeKc1_BomI__Fw) as the 
    owner of the ticket",
    "rdf:resource":"https://myjazzrtc.ibm.com:9000/ccm/oslc/users/_0k3H0MheEeKc1_BomI__Fw"
  }
}
  1. The script file reads every line in the bug report text file and calls Rational Team Concert's REST API to create defects.

Listing 8 is an example how the script appears.

Listing 8. Rational Team Concert REST call script
# put dynamic info in the payload
BUGDESC=`cat $QTXT1`
BLDDEFN=`grep ^buildDefinitionId= $BUILD_HOME/jazz.properties | awk -F= '{print $2}'`
BUILDID=`grep ^buildLabel= $BUILD_HOME/jazz.properties | awk -F= '{print $2}'`
sed -e "s%@BUGSUBJ@%$BUGDESC%g" -e "s/@BUILDID@/$BUILDID/g" -e "s/@BLDDEFN@/$BLDDEFN/g" 
new-defect.json >$PAYLOAD
PLSZ=`wc $PAYLOAD | awk '{print $3}'`
if [ $PLSZ -lt 1000 ]; then
  echo "...well, payload seems too small to be valid - please check.."
  cat $PAYLOAD
fi

# call the REST API
curl -s -D - -k -b $COOKIES -H "Content-Type: application/x-oslc-cm-change-request+
json" -H "Accept: text/xml" -X POST --data-binary @$PAYLOAD $HOST/oslc/contexts/$PROJ/
workitems >$JAZRESP

Conclusion

FindBugs, Cobertura, CheckStyle are widely-used tools for code quality assurance. The integration with Rational Team Concert helps programmers improve quality. With defect generation ease, manual intervention is avoided and extra work can be prevented. Integration with Rational Team Concert helps beginner coders get the most benefit out of it as it teaches them how to code in an efficient way.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational, Java development
ArticleID=994742
ArticleTitle=Integrating FindBugs, CheckStyle and Cobertura with Rational Team Concert build system
publish-date=01222015