A ruleset is an XML configuration file, which describes a collection of rules to be executed in a PMD run. PMD includes built-in rulesets to run quick analyses with a default configuration, but users are encouraged to make their own rulesets from the start, because they allow for so much configurability. This page walk you through the creation of a ruleset and the multiple configuration features offered by rulesets.
Table of Contents

Creating a ruleset

The first step is to create a new empty ruleset. You can use the following template:

<?xml version="1.0"?>

<ruleset name="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 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">

    <description>
        My custom rules
    </description>


    <!-- Your rules will come here -->

</ruleset>

Referencing a single rule

To use the built-in rules PMD provides, you need to add some references to them. Here’s a basic rule reference:

<rule ref="category/java/errorprone.xml/EmptyCatchBlock" />

Adding that element into the ruleset element adds the rule EmptyCatchBlock to your ruleset. This is a Java rule, so it will be executed on every Java file PMD encounters in its search space.

How to read the ref attribute?

  • category/java/errorprone.xml is a reference to the Java category errorprone. Since PMD 6.0.0, all PMD built-in rules are sorted in one of eight categories, which are consistent across languages:

    1. Best Practices: These are rules which enforce generally accepted best practices.
    2. Code Style: These rules enforce a specific coding style.
    3. Design: Rules that help you discover design issues.
    4. Documentation: These rules are related to code documentation.
    5. Error Prone: Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors.
    6. Multithreading: These are rules that flag issues when dealing with multiple threads of execution.
    7. Performance: Rules that flag suboptimal code.
    8. Security: Rules that flag potential security flaws.”
  • EmptyCatchBlock is simply the name of the rule. If there were no rule with that name within the specified category, then PMD would fail before starting the analysis.

Configuring individual rules

How you can configure individual rules is described on Configuring Rules.

Bulk-adding rules

You can also reference rules in bulk by referencing a complete category or ruleset, possibly excluding certain rules, like in the following:

<rule ref="category/java/codestyle.xml">
    <exclude name="WhileLoopsMustUseBraces"/>
    <exclude name="IfElseStmtsMustUseBraces"/>
</rule>

Here, the ref attribute references a whole category. You can also use a file system path or classpath relative path. In any case, the path must address an accessible ruleset XML file.

Filtering the processed files

You can exclude some files from being processed by a ruleset using exclude patterns, with an optional overriding include pattern. A file will be excluded from processing when there is a matching exclude pattern, but no matching include pattern. This exclude/include technique works regardless of how PMD is used (e.g. command line, IDE, Ant), making it easier to keep application of your PMD rules consistent throughout your environment. Here is an example:

<?xml version="1.0"?>
<ruleset name="myruleset"
		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 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
    <description>My ruleset</description>

    <exclude-pattern>.*/some/package/.*</exclude-pattern>
    <exclude-pattern>.*/some/other/package/FunkyClassNamePrefix.*</exclude-pattern>
    <include-pattern>.*/some/package/ButNotThisClass.*</include-pattern>

    <!-- Rules here ... -->

</ruleset>

Sharing your ruleset