Monthly Archives: June 2015

Writing your own custom PMD rules: PMD, Eclipse, Maven

How to write an own PMD rule?

  1. Create a new class (called rule in the following) that extends the PMD class AbstractJavaRule (see PMD documentation: How to write a rule class?).
    1. Override the visit methods which represent the Java syntax elements you want to analyze.
    2. Use the addViolation() methods within the visit methods to indicate a violation of your rule.
    3. Use the definePropertyDescriptor() method in the constructor to define a configuration parameter for your rule. Use the getProperty() method to read a configuration parameter within the visit method.
  2. Add your rule to a custom ruleset xml file (see PMD documentation: How to write a PMD rule?). Let us assume it is stored in a/b/c/my-ruleset.xml.
    Example ruleset file:

    <?xml version="1.0"?>
    <ruleset name="chw's custom rules" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
    
    <description>Christian Wulf's custom rules</description>
    
    <rule class="de.chw.MissingPluralVariableName" name="MissingPluralVariableName"
    message="The variable {0} is not named in plural although its type {1} represents a collection.">
    <description>
    A variable that represents a collection (incl. set and list) should be named in plural form.
    </description>
    
    <priority>1</priority>
    
    <example>
      <![CDATA[
      List<Stage> stages;
      Collection<String> words;
      ]]>
    </example>
    </rule>
    
    </ruleset>
  3. Package your compiled rule and the ruleset file (into an archive file, e.g., zip or jar).
  4. Now, you can include your ruleset archive into an arbitrary project ruleset file by inserting the following line:
    rule ref="a/b/c/my-ruleset.xml"

How to let the PMD Eclipse plugin recognize your own rule?

Shortest answer: avoid using the PMD Eclipse plugin. Instead, use the Lightweight Eclipse Plugin for Quality Assurance Tools.

Short answer: if you really need to use the PMD Eclipse plugin, then build an Eclipse fragment plugin for the PMD Eclipse plugin (see this link).

The most important paragraphs of the link are:

  1. Creating the plugin fragment in Eclipse
  2. Packaging and distributing the new rule
  3. Installing the new rule

How to check your own PMD rule via Maven

  1. Add the maven-pmd-plugin as plugin to your pom.xml.
  2. Add (your own) custom ruleset archives as a <dependency> of the plugin.
  3. Add your project-specific ruleset in <configuration><rulesets>....
  4. Define what goals should be executed in which phases in <executions>....

Example excerpt of a pom.xml:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-pmd-plugin</artifactId>
  <version>3.4</version>
  <dependencies>
    <dependency>
      <groupId>de.chw</groupId>
      <artifactId>pmd.ruleset</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <scope>system</scope>
      <systemPath>${project.basedir}/conf/quality-config/pmd/CustomPmdRules_1.0.0.201505130542.jar</systemPath>
    </dependency>
  </dependencies>
  <configuration>
    <rulesets>
      <ruleset>${project.basedir}/conf/quality-config/pmd-ruleset.xml</ruleset>
    </rulesets>
    <linkXref>true</linkXref>
    <includeTests>true</includeTests>
    <targetJdk>${java.version}</targetJdk>
    <failOnViolation>true</failOnViolation>
  </configuration>
  <executions>
    <execution>
      <phase>test</phase>
      <goals>
        <goal>pmd</goal>
        <goal>cpd</goal>
      </goals>
    </execution>
  </executions>
</plugin>