PMD doit être utilisé avec un jeu de règles personnalisé, qui permet de concentrer l’analyse sur les règles les plus pertinentes. Il est aussi possible, au lancement de PMD, de limiter l’analyse à une priorité minimale.
Pour mes audits, j’utilise généralement la ligne de commande suivante :
./pmd.sh ~/workspace/myproject/src csv sewatech-pmd.xml -reportfile sewatech.csv -minimumpriority 3
Cette commande génère un rapport au format CSV, avec la caractère ',' comme séparateur de champs.
J’utilise un jeu de règle de base (fichier sewatech-pmd.xml), valable pour PMD 4.2, que j’adapte en fonction des premières constatations :
<?xml version="1.0"?>
<ruleset name="auditcode"
xmlns="link:http://pmd.sf.net/ruleset/1.0.0[http://pmd.sf.net/ruleset/1.0.0]"
xmlns:xsi="link:http://www.w3.org/2001/XMLSchema-instance[http://www.w3.org/2001/XMLSchema-instance]"
xsi:schemaLocation="link:http://pmd.sf.net/ruleset/1.0.0[http://pmd.sf.net/ruleset/1.0.0] link:http://pmd.sf.net/ruleset_xml_schema.xsd[http://pmd.sf.net/ruleset_xml_schema.xsd]"
xsi:noNamespaceSchemaLocation="link:http://pmd.sf.net/ruleset_xml_schema.xsd[http://pmd.sf.net/ruleset_xml_schema.xsd]">
<rule ref="rulesets/basic.xml">
<exclude name="UselessOverridingMethod"/>
</rule>
<rule ref="rulesets/design.xml">
<exclude name="CloseResource"/>
<exclude name="ImmutableField"/>
<exclude name="UseSingleton"/>
<exclude name="SimpleDateFormatNeedsLocale"/>
<exclude name="UncommentedEmptyConstructor"/>
<exclude name="UseLocaleWithCaseConversions"/>
</rule>
<rule ref="rulesets/strings.xml">
<exclude name="AvoidDuplicateLiterals"/>
</rule>
<rule ref="rulesets/naming.xml/LongVariable">
<properties>
<property name="minimum" value="30"/>
</properties>
</rule>
<rule ref="rulesets/naming.xml">
<exclude name="AbstractNaming"/>
<exclude name="LongVariable"/>
</rule>
<rule ref="rulesets/braces.xml" />
<rule ref="rulesets/clone.xml" >
<exclude name="CloneThrowsCloneNotSupportedException"/>
</rule>
<rule ref="rulesets/codesize.xml/ExcessivePublicCount"
message="This class has a bunch of public methods and attributes (>100)">
<properties>
<property name="minimum" value="100"/>
</properties>
</rule>
<rule ref="rulesets/codesize.xml/TooManyFields"
message="Too many fields (>30)">
<properties>
<property name="minimum" value="30"/>
</properties>
</rule>
<rule ref="rulesets/codesize.xml">
<exclude name="CyclomaticComplexity"/>
<exclude name="ExcessivePublicCount"/>
<exclude name="TooManyFields"/>
<exclude name="NcssMethodCount"/>
<exclude name="NcssTypeCount"/>
<exclude name="NcssConstructorCount"/>
</rule>
<rule ref="rulesets/optimizations.xml" >
<exclude name="AvoidInstantiatingObjectsInLoops"/>
<exclude name="LocalVariableCouldBeFinal"/>
<exclude name="MethodArgumentCouldBeFinal"/>
</rule>
<rule ref="rulesets/coupling.xml" >
<exclude name="ExcessiveImports"/>
</rule>
<rule ref="rulesets/finalizers.xml" />
<rule ref="rulesets/imports.xml" />
<rule ref="rulesets/javabeans.xml">
<exclude name="BeanMembersShouldSerialize"/>
</rule>
<rule ref="rulesets/strictexception.xml" />
<rule ref="rulesets/sunsecure.xml">
<exclude name="ArrayIsStoredDirectly"/>
<exclude name="MethodReturnsInternalArray"/>
</rule>
<rule ref="rulesets/unusedcode.xml">
<exclude name="UnusedFormalParameter"/>
</rule>
<rule ref="rulesets/logging-jakarta-commons.xml" />
<rule ref="rulesets/logging-java.xml" />
</ruleset>
J’utilise aussi PMD intégré à Eclipse via le plug-in pmd-eclipse. Dans ce cas, j’utilise un autre jeu de règles(fichier .pmd.xml), plus léger, avec uniquement des règles de priorité 1 et 2. Comme le plug-in utilise une version plus ancienne de PMD (pmd-eclipse 1.8 ⇒ PMD 3.4), je dois désactiver certaines règles.
<?xml version="1.0"?>
<ruleset name="auditcode" xmlns="link:http://pmd.sf.net/ruleset/1.0.0[http://pmd.sf.net/ruleset/1.0.0]"
xmlns:xsi="link:http://www.w3.org/2001/XMLSchema-instance[http://www.w3.org/2001/XMLSchema-instance]"
xsi:schemaLocation="link:http://pmd.sf.net/ruleset/1.0.0[http://pmd.sf.net/ruleset/1.0.0] link:http://pmd.sf.net/ruleset_xml_schema.xsd[http://pmd.sf.net/ruleset_xml_schema.xsd]"
xsi:noNamespaceSchemaLocation="link:http://pmd.sf.net/ruleset_xml_schema.xsd[http://pmd.sf.net/ruleset_xml_schema.xsd]">
<rule ref="rulesets/basic.xml/BooleanInstantiation" />
<rule ref="rulesets/basic.xml/DoubleCheckedLocking" />
<rule ref="rulesets/design.xml/AvoidReassigningParameters" />
<rule ref="rulesets/design.xml/ConstructorCallsOverridableMethod" />
<rule ref="rulesets/design.xml/EqualsNull" />
<rule ref="rulesets/design.xml/AbstractClassWithoutAbstractMethod" />
<rule ref="rulesets/strings.xml/StringInstantiation" />
<rule ref="rulesets/naming.xml/MethodNamingConventions" />
<rule ref="rulesets/naming.xml/ClassNamingConventions" />
<rule ref="rulesets/naming.xml/VariableNamingConventions" />
<rule ref="rulesets/naming.xml/SuspiciousEqualsMethodName" />
<rule ref="rulesets/strictexception.xml/AvoidThrowingRawExceptionTypes" />
<rule ref="rulesets/strictexception.xml/AvoidThrowingNullPointerException" />
<rule ref="rulesets/logging-java.xml/LoggerIsNotStaticFinal" />
<rule ref="rulesets/logging-java.xml/MoreThanOneLogger" />
<rule ref="rulesets/logging-java.xml/SystemPrintln" />
</ruleset>