Author: Daniel Rubio
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>
<