Skip to Content
h5. Introduction   The Java code quality toolbox contains a lot of excellent, open source software. PMD is a tool that checks your Java source code against a set of rules and reports any discrepancies it finds. This blog entry contains an introduction to PMD and examples of how to write your own rules in Java and XPath.  h5. What is PMD?   [PMD |] is a static analysis tool. What this means is that PMD works by inspecting source code, whereas eg. JUnit works by actually running your code. PMD converts each Java source file into a so-called Abstract Syntax Tree (AST), which is a tree representation of the source. This tree is then examined by PMD rules, which look for unwanted patterns in the code. One rule might, for instance, look for while  loops whose loop bodies are not enclosed in braces. Another rule might look for collections that are being iterated over without the use of the for (Iterator i = collection.iterator(); i.hasNext(); )  idiom. PMD comes with a number of useful rules grouped into rule sets. For more information on the built-in rule sets, please refer to the PMD homepage.  h5. Using the Rule Designer utility   In order to write PMD rules, you need to understand how to navigate the Abstract Syntax Tree. The Rule Designer is a handy utility that lets you convert an arbitrary Java class into an AST. Run the Rule Designer by executing bin\designer.bat  below the PMD directory, type in or paste the Java code you want to analyse and click “Go”. Here’s an example:    PMD Rule Designer screenshot h5. Writing a PMD rule    PMD rules traverse the AST using the visitor design pattern  ( Each node in the AST accepts visitor objects. When a visitor is passed to a node, the node calls the visit  method on the visitor, handing it a reference to itself. The node’s class determines which of the several overloaded visit  methods will be called on the visitor object. In practice, new PMD rules extend the net.sourceforge.pmd.AbstractRule  class. AbstractRule  contains a number of overloaded visit  methods, inherited from net.sourceforge.pmd.ast.JavaParserVisitorAdapter . When writing a new rule, you only need to override the methods that handle the nodes that are relevant to the rule.     Let’s write a new rule. The purpose of our rule is to ensure that the names of class constants (ie. fields that are static and final) consist of only uppercase letters and the underscore character. By taking a closer look at the Rule Designer example above, we learn that we need to visit all FieldDeclarator nodes in the AST. This means we need to override the visit(ASTFieldDeclaration node, Object data)  method in our rule class. The complete source code of the rule follows below.    DISCLAIMER  : Please note that the following source code is provided for educational purposes +only+. It is +not+ intended for production use.     package;  import net.sourceforge.pmd.AbstractRule; import net.sourceforge.pmd.ast.ASTFieldDeclaration;  public class UpperCaseConstantsRule extends AbstractRule {      private static final String CONSTANT_NAME_PATTERN = “[A-Z]+(?:_[A-Z]+)*”;      public Object visit(ASTFieldDeclaration node, Object data) {         if (node.isFinal() && node.isStatic()) {             // The field is static and final             String name = node.getVariableName();             if (!name.matches(CONSTANT_NAME_PATTERN)) {                 // Add a rule violation to the report                 addViolation(data, node);             }         }         return super.visit(node, data);     }  }    The code is pretty straightforward. The return  statement, though, might not make immediate sense. By calling the overridden visit  method in the superclass, we make sure that children of the current node are also visited.  h5. Creating a ruleset XML document     h5. Running PMD   We’re now ready to run PMD. Assuming that the rule class is in your class path, run the pmd.bat  script as follows:   Running PMD on the command line   The first parameter is the name of a source file or a directory of source files. The second parameter is the report format. The third parameter is the name of the ruleset XML document. In this example, I’m running the newly created rule against its own source code. The UpperCaseConstantsRule  class does contain a class constant, but the name does not violate the rule. Let’s change that:      private static final String constantNamePattern = “[A-Z]+(?:_[A-Z]+)*”;     Running PMD again, we now get an error report indicating a problem on line 8 of :   PMD error report
To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply