PMD: A code analyzer for Java programmers

1014

Author: Daniel Rubio

Software execution efficiency is a highly coveted characteristic for any application, as it enhances response time, hardware utilization, and scalability, among a wealth of other resource-saving practices. PMD is an open source project designed to inspect Java code and point out inefficient structures such as unused local variables, duplicate import statements, or empty try/catch blocks. PMD gives programmers a preemptive approach to cleaning their code.

PMD inspects Java code using a rules-based approach. Rules can be defined either through XPath — an XML-based syntax — or a Java class. PMD includes a series of rules considered common in every Java application, all of which are included in its core distribution. They are organized in rulesets depending on their functionality.

Let’s illustrate a straightforward inspection using the basic and import rulesets provided with PMD, both of which include a series of predefined algorithms. Consider the following Java snippet:


import java.util.*; 
import java.sql.*;
import javax.sql.*;
// We already imported the whole java.util.* package - PMD rule violation
import java.util.Locale;

public class MyApp { 
       
    private String username;
        
    public void DBConnection() throws SQLException { 
	
	try {
	    DataSource ds; 
	    Connection conn;
	    // Rest of DB Connection code not shown for brevity
   
	} catch (Exception ioe) {
	    // No explicit error message  or code - PMD rule violation
	} finally { 
	    // No explicit message or code in finally message - PMD rule violation
	}

	// Unnecessary return, method returns void - PMD rule violation
	return; 
    }

}

The previous class outlines the series of rule violations which would be trapped by PMD. The actual inspection process can be done with the shell script included in PMD’s /etc directory with the following arguments:

 ./run.sh /src/*.java html rulesets/basic.xml,rulesets/imports.xml -jar pmd-2.0.jar

run.sh is the PMD script. It takes three arguments: /src/*.java indicates it should inspect every Java source file inside the /src directory (in a recursive manner); html specifies that it should create an HTML report with all the encountered rule violations (an XML report can be created using the alternate xml option); and rulesets/basic.xml,rulesets/imports.xml indicates the location of two PMD rulesets. The physical location of these rulesets is inside the PMD JAR file, which is why a fourth and optional parameter is defined: -jar pmd-2.0.jar.

Now that we have used PMD’s predefined rulesets, we will now create our own custom rule using XPath.

When using exceptions in Java programmers tend to employ the top hierarchy class Exception for declaring errors instead of specifying a more granular class. This often causes confusion in the debugging process, since every exception class is a derivative of this root class. The following XPath rule is designed to look up the use of this top-level class as well as other classes which can result in ambiguous interpretations.


<?xml version="1.0"?>

  <rule name="DontUseGeneralExceptions"
        message="Don't use a top level class for your exceptions, use a more granular class"
        class="net.sourceforge.pmd.rules.XPathRule">
    <description>
         Don't use Throwable, Exception or Error to generate exceptions 
    </description>
    <properties>
    <property name="xpath">
        <value>
        <![CDATA[
//AllocationExpression/Name[@Image='Throwable' |@Image='Exception' |@Image='Error'[[>
        </value>
    </property>
    </properties>
  </rule>

Every PMD rule definition is enclosed inside an XML-based file. The root <rule> tag contains three attributes: name, for descriptive purposes; message, which is used to provide a verbose explanation when the rule violation occurs; and class, which in this case has a value of net.sourceforge.pmd.rules.XPathRule — the base class for defining an PMD XPath rule.

Further down we enclose a <description> tag to provide a more explicit description to the rule. Finally, we define our XPath sequence within the <value> tag of the <property> element. The actual tree values that are navigated by XPath correspond to an abstract syntax generated by PMD using JavaCC. In other words, the AllocateExpression and @Image syntax are derived from analyzing your Java code, and are a translation of specific occurrences of Java structures.

If you’re curious as to how this special syntax is composed, you can feed Java code into a tool provided with PMD located under the /etc directory in a script named astviewer.sh. Upon invocation the Java code can be fed into the right pane to generate an abstract tree describing the source, easing the process of creating more complex XPath rules.

As to the actual invocation for using the custom rule, you use the following syntax:

 ./run.sh /src/*.java html rulesets/myrules.xml -jar pmd-2.0.jar

While this covers PMD’s command line execution and distinct variations for ruleset definitions, I invite you to explore its more advanced capabilities, such as its integration with other mainstream Java tools like Ant, Eclipse, and NetBeans for streamlining your class analysis, and in the process enhance your coding practices.

Daniel Rubio is the principal consultant at Osmosis Latina, a firm specializing in enterprise software development, training, and consulting, based in Mexico.

Category:

  • Java