How to run Findbugs, Pmd, Checkstyle, JUnit and Cobertrua with an Ant Build-Script?
The following Ant-build sample runs the five tools Findbugs [1], Checkstyle [2], PMD [3], JUnit [4] and Cobertura [5]. Additionally it creates and collects the native HTML reports of each tool.
Ant-builds have the big advantage over Maven-builds that you have everything under control and a minimal foot print of the build result.
This justifies the overhead of writing the build.xml file. The sometimes huge number of non needed libraries and difficult control of the used libraries is the main reason why I don't like Maven for real projects. Maven is better than Ant [7] for quick hacks.
Just copy the build.xml (file #1) in your project and change the paths checkstyle.home.dir, cobertura.home.dir,findbugs.home.dir and pmd.home.dir to your directories. This sample has been compiled and executed with junit-4.5.jar - but other versions should make no problem.
// File #1: build.xml
<project name="AntDefault" default="run" basedir=".">
<description>
Ant build sample for running
- findbugs,
- pmd,
- checkstyle,
- cobertrua and
- junit.
</description>
<!-- Change the paths to your individual installation directories -->
<property name="checkstyle.home.dir" location="C:/EU/checkstyle/checkstyle-5.0" />
<property name="cobertura.home.dir" value="C:/EU/cobertrua/cobertura-1.9.2" />
<property name="findbugs.home.dir" value="C:/EU//findbugs/findbugs-1.3.9-rc2" />
<property name="pmd.home.dir" value="C:/EU//pmd/pmd-4.2.5" />
<property name="lib.dir" location="${basedir}/lib" />
<property name="src.dir" location="${basedir}/src" />
<property name="bin.dir" location="${basedir}/bin" />
<property name="htm.dir" location="${basedir}/html" />
<property name="report.dir" location="${basedir}/report" />
<property name="report.checkstyle.dir" location="${report.dir}/checkstyle" />
<property name="report.junit.dir" location="${report.dir}/junit" />
<property name="report.findbugs.dir" location="${report.dir}/findbugs" />
<property name="report.cobertura.dir" location="${report.dir}/cobertura" />
<property name="report.pmd.dir" location="${report.dir}/pmd" />
<property name="instrumented.dir" location="${basedir}/instrumented" />
<property name="report.temp.dir" location="${report.dir}/temp" />
<property name="cobertura.ser.file" location="${report.temp.dir}/cobertura.ser" />
<path id="run.classpath">
<pathelement path="${bin.dir}" />
<pathelement path="${basedir}/lib/junit-4.5.jar" />
</path>
<path id="cobertura.classpath">
<path refid="run.classpath" />
<fileset dir="${cobertura.home.dir}">
<include name="cobertura.jar" />
<include name="lib/**/*.jar" />
</fileset>
</path>
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
<!-- -->
<target name="clean" description="Delete all result to start with a clean build.">
<delete dir="${report.junit.dir}" />
<delete dir="${report.findbugs.dir}" />
<delete dir="${report.cobertura.dir}" />
<delete dir="${report.checkstyles.dir}" />
<delete dir="${report.temp.dir}" />
<delete dir="${bin.dir}" />
</target>
<target name="prepare.report.dir" description="Prepares the reports folder">
<copy todir="${report.dir}">
<fileset dir="${htm.dir}">
<include name="*.htm" />
</fileset>
</copy>
</target>
<!-- -->
<target name="findbugs"
depends="compile"
description="Run code analysis over code to check for problems."
>
<!-- Fail this target if FindBugs is not installed. -->
<available file="${findbugs.home.dir}/lib/findbugs.jar" property="findbugs.available" />
<fail unless="findbugs.available"
message="Error: FINDBUGS_HOME not set or findbugs.jar not found."
/>
<taskdef name="findbugs"
classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
classpath="${findbugs.home.dir}/lib/findbugs-ant.jar"
/>
<!-- Run FindBugs. -->
<mkdir dir="${report.findbugs.dir}" />
<findbugs home="${findbugs.home.dir}"
workHard="true"
output="xml:withMessages"
outputFile="${report.findbugs.dir}/findbugs.xml"
>
<class location="${bin.dir}" />
<auxClasspath>
<fileset file="${basedir}/lib/junit-4.5.jar" />
</auxClasspath>
</findbugs>
</target>
<!-- -->
<path id="pmd2.classpath">
<pathelement location="${build}" />
<fileset dir="${pmd.home.dir}/lib/">
<include name="*.jar" />
</fileset>
</path>
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd2.classpath" />
<target name="report.pmd">
<mkdir dir="${report.pmd.dir}" />
<pmd rulesetfiles="rulesets/favorites.xml">
<formatter toFile="${report.pmd.dir}/pmd_report.xml" />
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
</pmd>
<xslt in="${report.pmd.dir}/pmd_report.xml"
out="${report.pmd.dir}/pmd_report.html"
/>
</target>
<!-- -->
<target name="compile" depends="clean" description="Compile the entire project.">
<mkdir dir="${bin.dir}" />
<javac debug="true"
debuglevel="lines, source"
srcdir="${src.dir}"
destdir="${bin.dir}"
classpathref="run.classpath"
/>
</target>
<!-- -->
<target name="cobertura.instrument"
depends="clean, compile"
description="Instrument the project for code coverage."
>
<mkdir dir="${report.temp.dir}" />
<cobertura-instrument todir="${instrumented.dir}" datafile="${cobertura.ser.file}">
<ignore regex="org.apache.log4j.*" />
<fileset dir="${bin.dir}">
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
</cobertura-instrument>
</target>
<!-- -->
<target name="junit"
depends="clean, compile, cobertura.instrument"
description="Run all junit test cases."
>
<mkdir dir="${report.cobertura.dir}" />
<mkdir dir="${report.temp.dir}" />
<junit printsummary="yes" fork="yes" haltonfailure="no">
<!-- Specify the name of the coverage data file to use.
The value specified below is the default. -->
<sysproperty key="net.sourceforge.cobertura.datafile" file="${cobertura.ser.file}" />
<!-- Note the classpath order: instrumented classes are before
the original (uninstrumented) classes. This is important. -->
<classpath location="${instrumented.dir}" />
<classpath location="${bin.dir}" />
<classpath location="${basedir}/lib/junit-4.5.jar}" />
<!-- The instrumented classes reference classes used by the
Cobertura runtime, so Cobertura and its dependencies
must be on your classpath. -->
<classpath refid="cobertura.classpath" />
<formatter />
<formatter />
<batchtest todir="${report.temp.dir}">
<fileset dir="${src.dir}">
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>
</target>
<!-- -->
<target name="report.junit" depends="junit" description="Create a report for the test result.">
<delete dir="${report.junit.dir}" />
<mkdir dir="${report.junit.dir}" />
<junitreport todir="${report.junit.dir}">
<fileset dir="${report.temp.dir}">
<include name="*.xml" />
</fileset>
<report format="frames" todir="${report.junit.dir}" />
</junitreport>
</target>
<!-- -->
<target name="report.findbugs" description="Generate a report on error analysis.">
<xslt in="${report.findbugs.dir}/findbugs.xml"
out="${report.findbugs.dir}/findbugs-default.html"
/>
</target>
<!-- -->
<target name="report.cobertura"
depends="junit"
description="Generate an HTML report on Cobertura."
>
<cobertura-report format="html"
datafile="${cobertura.ser.file}"
destdir="${report.cobertura.dir}"
>
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
</cobertura-report>
</target>
<!-- -->
<target name="report.checkstyle" description="Generate a report of code convention violations.">
<taskdef resource="checkstyletask.properties"
classpath="${checkstyle.home.dir}/checkstyle-all-5.0.jar"
/>
<!-- run verification of installation-->
<available file="${checkstyle.home.dir}/checkstyle-all-5.0.jar"
property="checkstyle.available"
/>
<fail unless="checkstyle.available"
message="Error: CHECKSTYLE_HOME not set or checkstyle-all-5.0.jar not found."
/>
<mkdir dir="${report.checkstyle.dir}" />
<!-- run analysis-->
<checkstyle config="${checkstyle.home.dir}/sun_checks.xml"
failureProperty="checkstyle.failure"
failOnViolation="false"
>
<formatter tofile="${report.checkstyle.dir}/checkstyle_report.xml" />
<fileset dir="${src.dir}" includes="**/*.java" />
</checkstyle>
<style in="${report.checkstyle.dir}/checkstyle_report.xml"
out="${report.checkstyle.dir}/checkstyle_report.html"
/>
</target>
<!-- -->
<target name="clean.temp" description="Delete all temporary files and folders.">
<delete dir="${instrumented.dir}" />
<delete dir="${report.temp.dir}" />
</target>
<!-- -->
<target name="run"
description="Run the build"
depends="clean,
prepare.report.dir,
report.checkstyle,
report.pmd,
compile,
cobertura.instrument,
junit,
report.junit,
findbugs,
report.findbugs,
report.cobertura,
clean.temp"
>
</target>
</project>
The build file expects to further files index.htm (File #2) and menue.htm (File #3) in the sub-directory "${basedir}/html". These two files create the entry page shown in figure 1.
// File #2: index.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<head>
<title>AntDefault Project Report</title>
<meta name="description" content="Beschreibung eintragen">
<meta name="keywords" content="Keywords eintragen, Keyword, Keyword, Keyword, Keyword, Keyword">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta name="author" content="Markus Sprunck">
<meta name="Content-Language" content="de">
</head>
<frameset framespacing="0" frameborder="no" border="0" >
<frameset framespacing="10" frameborder="yes" border="2" cols="100,*">
<frame name="nav" marginheight="0" marginwidth="0" src="menue.htm">
<frame name="anzeige" marginheight="0" marginwidth="0" src="cobertura\index.html">
</frameset>
</frameset>
</html>
// File #3: menue.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<style >
<!--
body {
font-family: Arial,sans-serif;
font-size:12px;
color: #F00800;
background-color:#EFEFEF;
margin:0px;
padding:0px;
}
td {
font-family: Arial,sans-serif;
font-size:12px;
color: #0A0000;
}
h2 {
font-family: Arial,sans-serif;
font-size:12px;
color: #5F5F5F;
}
#sub a {
display:block;
color:#5F5F5F;
text-decoration:none ;
font-family:Arial,Helvetica,sans-serif;
font-size: 13px;
width:100px;
background-color:#EFEFEF;
border-bottom:solid 1px #5F5F5F;
padding: 3px 0px 3px 8px;
}
#sub a:visited{
color:#5F5F5F;
text-decoration:none;
font-family:Arial,Helvetica,sans-serif;
font-size: 13px;
width:100px;
background-color:#EFEFEF;
border-bottom:solid 1px #5F5F5F;
padding: 3px 0px 3px 8px;
}
#sub a:hover {
color: #000000;
text-decoration:none ;
font-family:Arial,Helvetica,sans-serif;
font-size: 13px;
width:100px;
background-color:#FFFFFF;
border-bottom:solid 1px #000000;
}
-->
</style>
</head>
<body vlink="#000000" alink="#FFFFFF" link="#000000" text="#000000" id="sub">
<table border="0" cellspacing="0" cellpadding="0" width="100%" height="100%">
<tr><td valign="top">
<div id="sub">
<a target="anzeige" href="checkstyle\checkstyle_report.html">checkstyle</a>
<a target="anzeige" href="cobertura\index.html">cobertrua</a>
<a target="anzeige" href="findbugs\findbugs-default.html">findbugs</a>
<a target="anzeige" href="junit\index.html">junit</a>
<a target="anzeige" href="pmd\pmd_report.html">pmd</a>
</div>
</td></tr>
</table>
</body></html>The Ant-build and results of static and dynamic code analysis can also easily be managed and visualized with Hudson [6].
[1] FindBugs™ is a static code analysis tool that analyses Java bytecode and detects a wide range of problems;http://findbugs.sourceforge.net
[2] Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard;
http://checkstyle.sourceforge.net
[3] PMD scans source code and looks for potential problems possible bugs, unused and sub-optimal code and over-complicated expressions; http://pmd.sourceforge.net/pmd-5.0.0
[4] JUnit is a unit testing framework for the Java programming language; http://www.junit.org
[5] Cobertura is a Java code coverage analysis tool. You can use it to determine what percentage of your source code is excercised by your unit tests; http://cobertura.sourceforge.net;
[6] Hudson is an extensible Continuous Integration Server; http://hudson-ci.org;
[7] Apache Ant™ is a Java library and command-line tool whose mission is to drive processes described in build files as targets and extension points dependent upon each other; http://ant.apache.org;
Ant-builds have the big advantage over Maven-builds that you have everything under control and a minimal foot print of the build result.
This justifies the overhead of writing the build.xml file. The sometimes huge number of non needed libraries and difficult control of the used libraries is the main reason why I don't like Maven for real projects. Maven is better than Ant [7] for quick hacks.
Just copy the build.xml (file #1) in your project and change the paths checkstyle.home.dir, cobertura.home.dir,findbugs.home.dir and pmd.home.dir to your directories. This sample has been compiled and executed with junit-4.5.jar - but other versions should make no problem.
// File #1: build.xml
<project name="AntDefault" default="run" basedir=".">
<description>
Ant build sample for running
- findbugs,
- pmd,
- checkstyle,
- cobertrua and
- junit.
</description>
<!-- Change the paths to your individual installation directories -->
<property name="checkstyle.home.dir" location="C:/EU/checkstyle/checkstyle-5.0" />
<property name="cobertura.home.dir" value="C:/EU/cobertrua/cobertura-1.9.2" />
<property name="findbugs.home.dir" value="C:/EU//findbugs/findbugs-1.3.9-rc2" />
<property name="pmd.home.dir" value="C:/EU//pmd/pmd-4.2.5" />
<property name="lib.dir" location="${basedir}/lib" />
<property name="src.dir" location="${basedir}/src" />
<property name="bin.dir" location="${basedir}/bin" />
<property name="htm.dir" location="${basedir}/html" />
<property name="report.dir" location="${basedir}/report" />
<property name="report.checkstyle.dir" location="${report.dir}/checkstyle" />
<property name="report.junit.dir" location="${report.dir}/junit" />
<property name="report.findbugs.dir" location="${report.dir}/findbugs" />
<property name="report.cobertura.dir" location="${report.dir}/cobertura" />
<property name="report.pmd.dir" location="${report.dir}/pmd" />
<property name="instrumented.dir" location="${basedir}/instrumented" />
<property name="report.temp.dir" location="${report.dir}/temp" />
<property name="cobertura.ser.file" location="${report.temp.dir}/cobertura.ser" />
<path id="run.classpath">
<pathelement path="${bin.dir}" />
<pathelement path="${basedir}/lib/junit-4.5.jar" />
</path>
<path id="cobertura.classpath">
<path refid="run.classpath" />
<fileset dir="${cobertura.home.dir}">
<include name="cobertura.jar" />
<include name="lib/**/*.jar" />
</fileset>
</path>
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
<!-- -->
<target name="clean" description="Delete all result to start with a clean build.">
<delete dir="${report.junit.dir}" />
<delete dir="${report.findbugs.dir}" />
<delete dir="${report.cobertura.dir}" />
<delete dir="${report.checkstyles.dir}" />
<delete dir="${report.temp.dir}" />
<delete dir="${bin.dir}" />
</target>
<target name="prepare.report.dir" description="Prepares the reports folder">
<copy todir="${report.dir}">
<fileset dir="${htm.dir}">
<include name="*.htm" />
</fileset>
</copy>
</target>
<!-- -->
<target name="findbugs"
depends="compile"
description="Run code analysis over code to check for problems."
>
<!-- Fail this target if FindBugs is not installed. -->
<available file="${findbugs.home.dir}/lib/findbugs.jar" property="findbugs.available" />
<fail unless="findbugs.available"
message="Error: FINDBUGS_HOME not set or findbugs.jar not found."
/>
<taskdef name="findbugs"
classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
classpath="${findbugs.home.dir}/lib/findbugs-ant.jar"
/>
<!-- Run FindBugs. -->
<mkdir dir="${report.findbugs.dir}" />
<findbugs home="${findbugs.home.dir}"
workHard="true"
output="xml:withMessages"
outputFile="${report.findbugs.dir}/findbugs.xml"
>
<class location="${bin.dir}" />
<auxClasspath>
<fileset file="${basedir}/lib/junit-4.5.jar" />
</auxClasspath>
</findbugs>
</target>
<!-- -->
<path id="pmd2.classpath">
<pathelement location="${build}" />
<fileset dir="${pmd.home.dir}/lib/">
<include name="*.jar" />
</fileset>
</path>
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd2.classpath" />
<target name="report.pmd">
<mkdir dir="${report.pmd.dir}" />
<pmd rulesetfiles="rulesets/favorites.xml">
<formatter toFile="${report.pmd.dir}/pmd_report.xml" />
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
</pmd>
<xslt in="${report.pmd.dir}/pmd_report.xml"
out="${report.pmd.dir}/pmd_report.html"
/>
</target>
<!-- -->
<target name="compile" depends="clean" description="Compile the entire project.">
<mkdir dir="${bin.dir}" />
<javac debug="true"
debuglevel="lines, source"
srcdir="${src.dir}"
destdir="${bin.dir}"
classpathref="run.classpath"
/>
</target>
<!-- -->
<target name="cobertura.instrument"
depends="clean, compile"
description="Instrument the project for code coverage."
>
<mkdir dir="${report.temp.dir}" />
<cobertura-instrument todir="${instrumented.dir}" datafile="${cobertura.ser.file}">
<ignore regex="org.apache.log4j.*" />
<fileset dir="${bin.dir}">
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
</cobertura-instrument>
</target>
<!-- -->
<target name="junit"
depends="clean, compile, cobertura.instrument"
description="Run all junit test cases."
>
<mkdir dir="${report.cobertura.dir}" />
<mkdir dir="${report.temp.dir}" />
<junit printsummary="yes" fork="yes" haltonfailure="no">
<!-- Specify the name of the coverage data file to use.
The value specified below is the default. -->
<sysproperty key="net.sourceforge.cobertura.datafile" file="${cobertura.ser.file}" />
<!-- Note the classpath order: instrumented classes are before
the original (uninstrumented) classes. This is important. -->
<classpath location="${instrumented.dir}" />
<classpath location="${bin.dir}" />
<classpath location="${basedir}/lib/junit-4.5.jar}" />
<!-- The instrumented classes reference classes used by the
Cobertura runtime, so Cobertura and its dependencies
must be on your classpath. -->
<classpath refid="cobertura.classpath" />
<formatter />
<formatter />
<batchtest todir="${report.temp.dir}">
<fileset dir="${src.dir}">
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>
</target>
<!-- -->
<target name="report.junit" depends="junit" description="Create a report for the test result.">
<delete dir="${report.junit.dir}" />
<mkdir dir="${report.junit.dir}" />
<junitreport todir="${report.junit.dir}">
<fileset dir="${report.temp.dir}">
<include name="*.xml" />
</fileset>
<report format="frames" todir="${report.junit.dir}" />
</junitreport>
</target>
<!-- -->
<target name="report.findbugs" description="Generate a report on error analysis.">
<xslt in="${report.findbugs.dir}/findbugs.xml"
out="${report.findbugs.dir}/findbugs-default.html"
/>
</target>
<!-- -->
<target name="report.cobertura"
depends="junit"
description="Generate an HTML report on Cobertura."
>
<cobertura-report format="html"
datafile="${cobertura.ser.file}"
destdir="${report.cobertura.dir}"
>
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
</cobertura-report>
</target>
<!-- -->
<target name="report.checkstyle" description="Generate a report of code convention violations.">
<taskdef resource="checkstyletask.properties"
classpath="${checkstyle.home.dir}/checkstyle-all-5.0.jar"
/>
<!-- run verification of installation-->
<available file="${checkstyle.home.dir}/checkstyle-all-5.0.jar"
property="checkstyle.available"
/>
<fail unless="checkstyle.available"
message="Error: CHECKSTYLE_HOME not set or checkstyle-all-5.0.jar not found."
/>
<mkdir dir="${report.checkstyle.dir}" />
<!-- run analysis-->
<checkstyle config="${checkstyle.home.dir}/sun_checks.xml"
failureProperty="checkstyle.failure"
failOnViolation="false"
>
<formatter tofile="${report.checkstyle.dir}/checkstyle_report.xml" />
<fileset dir="${src.dir}" includes="**/*.java" />
</checkstyle>
<style in="${report.checkstyle.dir}/checkstyle_report.xml"
out="${report.checkstyle.dir}/checkstyle_report.html"
/>
</target>
<!-- -->
<target name="clean.temp" description="Delete all temporary files and folders.">
<delete dir="${instrumented.dir}" />
<delete dir="${report.temp.dir}" />
</target>
<!-- -->
<target name="run"
description="Run the build"
depends="clean,
prepare.report.dir,
report.checkstyle,
report.pmd,
compile,
cobertura.instrument,
junit,
report.junit,
findbugs,
report.findbugs,
report.cobertura,
clean.temp"
>
</target>
</project>
The build file expects to further files index.htm (File #2) and menue.htm (File #3) in the sub-directory "${basedir}/html". These two files create the entry page shown in figure 1.
// File #2: index.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<head>
<title>AntDefault Project Report</title>
<meta name="description" content="Beschreibung eintragen">
<meta name="keywords" content="Keywords eintragen, Keyword, Keyword, Keyword, Keyword, Keyword">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta name="author" content="Markus Sprunck">
<meta name="Content-Language" content="de">
</head>
<frameset framespacing="0" frameborder="no" border="0" >
<frameset framespacing="10" frameborder="yes" border="2" cols="100,*">
<frame name="nav" marginheight="0" marginwidth="0" src="menue.htm">
<frame name="anzeige" marginheight="0" marginwidth="0" src="cobertura\index.html">
</frameset>
</frameset>
</html>
// File #3: menue.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<style >
<!--
body {
font-family: Arial,sans-serif;
font-size:12px;
color: #F00800;
background-color:#EFEFEF;
margin:0px;
padding:0px;
}
td {
font-family: Arial,sans-serif;
font-size:12px;
color: #0A0000;
}
h2 {
font-family: Arial,sans-serif;
font-size:12px;
color: #5F5F5F;
}
#sub a {
display:block;
color:#5F5F5F;
text-decoration:none ;
font-family:Arial,Helvetica,sans-serif;
font-size: 13px;
width:100px;
background-color:#EFEFEF;
border-bottom:solid 1px #5F5F5F;
padding: 3px 0px 3px 8px;
}
#sub a:visited{
color:#5F5F5F;
text-decoration:none;
font-family:Arial,Helvetica,sans-serif;
font-size: 13px;
width:100px;
background-color:#EFEFEF;
border-bottom:solid 1px #5F5F5F;
padding: 3px 0px 3px 8px;
}
#sub a:hover {
color: #000000;
text-decoration:none ;
font-family:Arial,Helvetica,sans-serif;
font-size: 13px;
width:100px;
background-color:#FFFFFF;
border-bottom:solid 1px #000000;
}
-->
</style>
</head>
<body vlink="#000000" alink="#FFFFFF" link="#000000" text="#000000" id="sub">
<table border="0" cellspacing="0" cellpadding="0" width="100%" height="100%">
<tr><td valign="top">
<div id="sub">
<a target="anzeige" href="checkstyle\checkstyle_report.html">checkstyle</a>
<a target="anzeige" href="cobertura\index.html">cobertrua</a>
<a target="anzeige" href="findbugs\findbugs-default.html">findbugs</a>
<a target="anzeige" href="junit\index.html">junit</a>
<a target="anzeige" href="pmd\pmd_report.html">pmd</a>
</div>
</td></tr>
</table>
</body></html>The Ant-build and results of static and dynamic code analysis can also easily be managed and visualized with Hudson [6].
[1] FindBugs™ is a static code analysis tool that analyses Java bytecode and detects a wide range of problems;http://findbugs.sourceforge.net
[2] Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard;
http://checkstyle.sourceforge.net
[3] PMD scans source code and looks for potential problems possible bugs, unused and sub-optimal code and over-complicated expressions; http://pmd.sourceforge.net/pmd-5.0.0
[4] JUnit is a unit testing framework for the Java programming language; http://www.junit.org
[5] Cobertura is a Java code coverage analysis tool. You can use it to determine what percentage of your source code is excercised by your unit tests; http://cobertura.sourceforge.net;
[6] Hudson is an extensible Continuous Integration Server; http://hudson-ci.org;
[7] Apache Ant™ is a Java library and command-line tool whose mission is to drive processes described in build files as targets and extension points dependent upon each other; http://ant.apache.org;