2009-04-02

Static Analysis Tools

I'm evaluating static analysis tools for my Master's program at Cal Lutheran University. I'm finding the subject intriguing. Static analysis programs test code for potential flaws and are contrasted with dynamic testing tools like JUnit. They check code for deviations from established best practices, good design standards and possible serious issues. In my experience so far these tools generally do a good job. At the minimum they are useful for learning. One might not even always agree with the results but they are often interesting from an academic standpoint. It's especially fun to run them on popular open source projects. It's therapeutic for the ego to realize how pervasive certain bad practices are. By that token, running them on one's own projects might help one avoid such embarrassments.

The best of breed in the Java space are: FindBugs, PMD and Checkstyle. Each of the tools have different focuses, Checkstyle being oriented towards formatting conventions for instance (although also evaluating for more serious issues). One interesting thing is that they all seem to find different problems so they work well in conjunction. They each have IDE integration, specifically Eclipse plugins. Also they each have build tool integration with ANT. I think a development environment can benefit greatly by using both these features: use them in the IDE for real time preemption and then integrate into the automatic builds to ensure clean code across the team (I dub the concept Bug Brother). Few could argue the benefits of clean code for bug avoidance and maintenance. Best practices are in many cases well established across the industry but even good programmers can find it difficult to keep them all straight and to maintain the discipline to apply them. Tools like these can keep us honest. Let's use them.

Here's a sample Ant build.xml snippet from my project (the one I hope to share more on soon):

<taskdef name="findbugs"
classpath="${findbugs.home}/lib/findbugs.jar"
classname="edu.umd.cs.findbugs.anttask.FindBugsTask" />

<target name="findbugs" depends="build">
<findbugs home="${findbugs.home}" output="xml"
outputFile="bcel-fb.xml">
<sourcePath path="${src.dir}" />
<class location="${build.dir}" />
<auxClasspath path="${web.dir}/WEB-INF/lib/spring.jar" />
<auxClasspath path="${web.dir}/WEB-INF/lib/spring-webmvc.jar" />
<auxClasspath path="${web.dir}/WEB-INF/lib/persistence.jar" />
<auxClasspath path="${web.dir}/WEB-INF/lib/commons-logging.jar" />
<auxClasspath path="${web.dir}/WEB-INF/lib/servlet-api.jar" />
</findbugs>
</target>

<taskdef resource="checkstyletask.properties"
classpath="${checkstyle.home}/checkstyle-all-5.0-beta2.jar"/>

<target name="checkstyle"
description="Generates a report of code convention violations.">

<checkstyle config="sun_checks.xml"
failureProperty="checkstyle.failure"
failOnViolation="false">
<formatter type="xml" tofile="checkstyle_report.xml"/>
<fileset dir="${src.dir}" includes="**/*.java"/>
</checkstyle>
</target>

<path id="pmd.classpath">
<pathelement location="${build}"/>
<fileset dir="${pmd.home}/lib/">
<include name="*.jar"/>
</fileset>
</path>

<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask"
classpathref="pmd.classpath"/>

<target name="pmd">
<pmd>
<ruleset>basic,imports,unusedcode,strings</ruleset>
<formatter type="net.sourceforge.pmd.renderers.HTMLRenderer"
toFile="pmdout.html"/>
<fileset dir="src">
<include name="**/*.java"/>
</fileset>
</pmd>
</target>

<target name="analysis" depends="build,findbugs,checkstyle,pmd"/>

No comments:

Post a Comment