If you have used such plugins in your project as FindBugs, Checkstyle etc then you quite likely have heard of PMD too. (I have used these tools initially with Apache Maven and nowadays use them via Gradle in my builds, but there’s lots of support for others tools, Ant included.)
The trouble with PMD as I found is that my style of coding needs some configuration for this tool — and simply just referencing the out-of-the-box rulesets in my build didn’t quite cut as it renders warnings I frankly don’t care about 🙂 (Either that, or worse, it let items fall through the cracks and missed certain things if I relaxed it too much.)
So I have found myself build a ruleset to just simply use across my projects — and pushed it on Github for others to use it. That is to say it’s not enough for me to just (ahem!)
enforce suggest my code style onto my colleagues, but I want the whole world to embrace it 🙂
I’m planning on updating this regularly — as you know, PMD just like any other projects occasionally retires some rules as well as adds some more (we’re still waiting for the Java 8 ones guys, by the way!), so I’m sure this “project” will suffer some iterations. Since there are often incompatibilities with some of these checks which get added or removed in versions of PMD, I’ll make sure the “readme” of this repo will always state the version of the plugin this works with.
Note: some of the PMD docco still out there is outdated by now, the old doccos mention references to rulesets in the format:
<rule ref="rulesets/basic.xml/AvoidMultipleUnaryOperators"> <priority>4</priority> </rule>
That was correct before version 5 of the tool — with version 5 you need to include the language/target in the ruleset ref:
<rule ref="rulesets/java/basic.xml/AvoidMultipleUnaryOperators"> <priority>4</priority> </rule>
If you don’t do that you will get the dreaded error message:
Execution failed for task ':.....:pmdMain'. > Can't find resource 'rulesets/basic.xml' for rule 'AvoidMultipleUnaryOperators'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Here's the current classpath: ....
Be mindful of that when updating your PMD rulesets if you don’t want to use my ruleset here.
Also note that I have based the rules priority in my ruleset on these recommendations from the PMD team which states http://pmd.github.io/pmd-5.0.5/rule-guidelines.html :
Rule priority may, of course, changes a lot depending on the context of the project. However, you can use the following guidelines to assert the legitimate priority of your rule:
- Change absolutely required. Behavior is critically broken/buggy.
- Change highly recommended. Behavior is quite likely to be broken/buggy.
- Change recommended. Behavior is confusing, perhaps buggy, and/or against standards/best practices.
- Change optional. Behavior is not likely to be buggy, but more just flies in the face of standards/style/good taste.
- Change highly optional. Nice to have, such as a consistent naming policy for package/class/fields…
As such I’ve weighted the rules in my ruleset in accordance to what I considered to be required vs highly optional — please note that this is quite a subjective matter and can differ in fact from project to project so please be sure to check if these match your project needs.
With that in mind, here’s the Github repo with my PMD rulesets: https://github.com/liviutudor/PmdRulesets — or if you prefer the file directly: https://github.com/liviutudor/PmdRulesets/blob/master/ruleset.xml . (Comments and pull requests welcome, of course!)