We check our codebase against a custom set of PMD rules, but sometimes we'd like to ignore of some of them, tipically for IDE-generated code (e.g. hashCode ) or when overriding methods (e.g. methods throwing raw exceptions).
The best possibility we've found is tied to the built-in SuppressWarnings annotations you get in Java 5: if you want to ignore all PMD warnings for the hashCode method you simply have to add the line
@SuppressWarnings("PMD")
before your method. If you want to exclude a specific rule you can use the syntax
@SuppressWarnings("PMD.SignatureDeclareThrowsException")
while for more than a rule the line gets something like
@SuppressWarnings({"PMD.LongVariable", "PMD.DefaultPackage"})
The annotation can be applied to all the available levels: class, constructor, field, method, local variable, and so on and so forth.
You could also add the (customizable) comment //NOPMD on the same line for which you experience the warning, but it is much less elegant and powerful.
Showing posts with label PMD. Show all posts
Showing posts with label PMD. Show all posts
Thursday, July 10, 2008
Tuesday, July 8, 2008
Divide et impera
Following this ancient rule (and Uncle Bob's suggestions) we recently separated our new development effort into four subproject, each of which focuses on a particular aspect of the whole project. The separation is also based on the techniques for splitting the different domain aspects explained in DDD.
Everything has been integrated in Hudson, with the Cobertura, Open Tasks and Violations (with PMD) plugins.
We still have to reintroduce JDepend, but we'll do it in a short while.
Everything has been integrated in Hudson, with the Cobertura, Open Tasks and Violations (with PMD) plugins.
We still have to reintroduce JDepend, but we'll do it in a short while.
Etichette:
cobertura,
dependencies-breaking,
design,
domain-driven design,
Hudson,
PMD
Wednesday, March 12, 2008
PMD rules for test classes
This is the updated version of the PMD ruleset we use for test classes:
<?xml version="1.0"?>
<ruleset name="my_pmd_test_rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
All the rules except the ones we don't like
</description>
<rule ref="rulesets/basic.xml"/>
<rule ref="rulesets/braces.xml"/>
<rule ref="rulesets/clone.xml"/>
<rule ref="rulesets/codesize.xml"/>
<rule ref="rulesets/controversial.xml">
<exclude name="AtLeastOneConstructor" />
<exclude name="UnnecessaryConstructor" />
</rule>
<rule ref="rulesets/coupling.xml"/>
<rule ref="rulesets/design.xml">
<exclude name="UncommentedEmptyConstructor" />
<exclude name="UncommentedEmptyMethod" />
</rule>
<rule ref="rulesets/finalizers.xml"/>
<rule ref="rulesets/imports.xml"/>
<rule ref="rulesets/j2ee.xml"/>
<rule ref="rulesets/junit.xml">
<exclude name="TestClassWithoutTestCases" />
</rule>
<rule ref="rulesets/javabeans.xml"/>
<rule ref="rulesets/logging-java.xml">
<exclude name="SystemPrintln" />
</rule>
<rule ref="rulesets/naming.xml"/>
<rule ref="rulesets/optimizations.xml">
<exclude name="LocalVariableCouldBeFinal" />
</rule>
<rule ref="rulesets/scratchpad.xml"/>
<rule ref="rulesets/strictexception.xml">
<exclude name="SignatureDeclareThrowsException" />
</rule>
<rule ref="rulesets/strings.xml"/>
<rule ref="rulesets/sunsecure.xml"/>
<rule ref="rulesets/typeresolution.xml">
<exclude name="SignatureDeclareThrowsException" />
</rule>
<rule ref="rulesets/unusedcode.xml"/>
</ruleset>
Some of the rules, e.g. UnnecessaryConstructor, were excluded only because of the IDE generates test classes.
<?xml version="1.0"?>
<ruleset name="my_pmd_test_rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
All the rules except the ones we don't like
</description>
<rule ref="rulesets/basic.xml"/>
<rule ref="rulesets/braces.xml"/>
<rule ref="rulesets/clone.xml"/>
<rule ref="rulesets/codesize.xml"/>
<rule ref="rulesets/controversial.xml">
<exclude name="AtLeastOneConstructor" />
<exclude name="UnnecessaryConstructor" />
</rule>
<rule ref="rulesets/coupling.xml"/>
<rule ref="rulesets/design.xml">
<exclude name="UncommentedEmptyConstructor" />
<exclude name="UncommentedEmptyMethod" />
</rule>
<rule ref="rulesets/finalizers.xml"/>
<rule ref="rulesets/imports.xml"/>
<rule ref="rulesets/j2ee.xml"/>
<rule ref="rulesets/junit.xml">
<exclude name="TestClassWithoutTestCases" />
</rule>
<rule ref="rulesets/javabeans.xml"/>
<rule ref="rulesets/logging-java.xml">
<exclude name="SystemPrintln" />
</rule>
<rule ref="rulesets/naming.xml"/>
<rule ref="rulesets/optimizations.xml">
<exclude name="LocalVariableCouldBeFinal" />
</rule>
<rule ref="rulesets/scratchpad.xml"/>
<rule ref="rulesets/strictexception.xml">
<exclude name="SignatureDeclareThrowsException" />
</rule>
<rule ref="rulesets/strings.xml"/>
<rule ref="rulesets/sunsecure.xml"/>
<rule ref="rulesets/typeresolution.xml">
<exclude name="SignatureDeclareThrowsException" />
</rule>
<rule ref="rulesets/unusedcode.xml"/>
</ruleset>
Some of the rules, e.g. UnnecessaryConstructor, were excluded only because of the IDE generates test classes.
Etichette:
PMD
Friday, March 7, 2008
PMD in NetBeans
PMD statically scans Java code looking for potential problems like unused variables, duplicated code, and a lot of other things. PMD is integrated with NetBeans, with the possibility to select the rules to apply and to have an online scan while coding.
PMD also offers an Ant task: we can add the following lines to the build.xml file:
<target depends="init" name="pmd">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpath="${libs.PMD.classpath}">
<pmd rulesetfiles="${pmd.dir}/my_pmd_rules.xml">
<formatter type="xml" tofile="pmd_report.xml"/>
<fileset dir="src/">
<include name="**/*.java"/>
</fileset>
</pmd>
</taskdef>
</target>
I have shown two different ways of referencing external files or libraries. For the PMD classpath I created a new library in NetBeans and used the variable libs.PMD.classpath that the IDE stored in the .netbeans/6.0/build.properties files in the user's home directory. For the ruleset files I added the pmd.dir property to the private/private.properties file.
Both approaches work, but the second is preferable if you have to build on a CI server, as the first method requires to add a library to the local NetBeans installation (you need to have one, as NetBeans build files use IDE-managed technologies); if you can only access the CI server via ssh this option is... not an option; you can always manually edit the build.properties files but IMHO it's a little awkward.
Modifying the private/private.properties files makes it easy to have different path on the developers' pc and on the CI server.
To define a set of rules you need to create an XML file as follows:
<?xml version="1.0"?>
<ruleset name="my_pmd_rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
All the rules except the ones we don't like
</description>
<rule ref="rulesets/basic.xml"/>
<rule ref="rulesets/braces.xml"/>
<rule ref="rulesets/clone.xml"/>
<rule ref="rulesets/codesize.xml"/>
<rule ref="rulesets/controversial.xml">
<exclude name="AtLeastOneConstructor" />
</rule>
<rule ref="rulesets/coupling.xml"/>
<rule ref="rulesets/design.xml"/>
<rule ref="rulesets/finalizers.xml"/>
<rule ref="rulesets/imports.xml"/>
<rule ref="rulesets/j2ee.xml"/>
<rule ref="rulesets/junit.xml"/>
<rule ref="rulesets/javabeans.xml"/>
<rule ref="rulesets/naming.xml"/>
<rule ref="rulesets/optimizations.xml">
<exclude name="LocalVariableCouldBeFinal" />
</rule>
<rule ref="rulesets/scratchpad.xml"/>
<rule ref="rulesets/strictexception.xml"/>
<rule ref="rulesets/strings.xml"/>
<rule ref="rulesets/sunsecure.xml"/>
<rule ref="rulesets/typeresolution.xml"/>
<rule ref="rulesets/unusedcode.xml"/>
</ruleset>
In this file I choose all the available rulesets and simply excluded the rules I don't mean to use; the syntax is straightforward.
If we wanted to check the test classes' sources it would suffice to add the following lines
<fileset dir="test/">
<include name="**/*.java"/>
</fileset>
to the pmd task, even if it would be better to define a new Ant target (e.g. pmd-testclasses) as test classes should be validated against different rules.
PMD also offers an Ant task: we can add the following lines to the build.xml file:
<target depends="init" name="pmd">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpath="${libs.PMD.classpath}">
<pmd rulesetfiles="${pmd.dir}/my_pmd_rules.xml">
<formatter type="xml" tofile="pmd_report.xml"/>
<fileset dir="src/">
<include name="**/*.java"/>
</fileset>
</pmd>
</taskdef>
</target>
I have shown two different ways of referencing external files or libraries. For the PMD classpath I created a new library in NetBeans and used the variable libs.PMD.classpath that the IDE stored in the .netbeans/6.0/build.properties files in the user's home directory. For the ruleset files I added the pmd.dir property to the private/private.properties file.
Both approaches work, but the second is preferable if you have to build on a CI server, as the first method requires to add a library to the local NetBeans installation (you need to have one, as NetBeans build files use IDE-managed technologies); if you can only access the CI server via ssh this option is... not an option; you can always manually edit the build.properties files but IMHO it's a little awkward.
Modifying the private/private.properties files makes it easy to have different path on the developers' pc and on the CI server.
To define a set of rules you need to create an XML file as follows:
<?xml version="1.0"?>
<ruleset name="my_pmd_rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
All the rules except the ones we don't like
</description>
<rule ref="rulesets/basic.xml"/>
<rule ref="rulesets/braces.xml"/>
<rule ref="rulesets/clone.xml"/>
<rule ref="rulesets/codesize.xml"/>
<rule ref="rulesets/controversial.xml">
<exclude name="AtLeastOneConstructor" />
</rule>
<rule ref="rulesets/coupling.xml"/>
<rule ref="rulesets/design.xml"/>
<rule ref="rulesets/finalizers.xml"/>
<rule ref="rulesets/imports.xml"/>
<rule ref="rulesets/j2ee.xml"/>
<rule ref="rulesets/junit.xml"/>
<rule ref="rulesets/javabeans.xml"/>
<rule ref="rulesets/naming.xml"/>
<rule ref="rulesets/optimizations.xml">
<exclude name="LocalVariableCouldBeFinal" />
</rule>
<rule ref="rulesets/scratchpad.xml"/>
<rule ref="rulesets/strictexception.xml"/>
<rule ref="rulesets/strings.xml"/>
<rule ref="rulesets/sunsecure.xml"/>
<rule ref="rulesets/typeresolution.xml"/>
<rule ref="rulesets/unusedcode.xml"/>
</ruleset>
In this file I choose all the available rulesets and simply excluded the rules I don't mean to use; the syntax is straightforward.
If we wanted to check the test classes' sources it would suffice to add the following lines
<fileset dir="test/">
<include name="**/*.java"/>
</fileset>
to the pmd task, even if it would be better to define a new Ant target (e.g. pmd-testclasses) as test classes should be validated against different rules.
Thursday, March 6, 2008
My baby Hudson is growing...
We are starting a brand new project (er... that would actually be a third rework, as it is an inherited legacy application which had been already reworked twice from a previous group of developers) which will be the first real one on which we shall use a CI server; the selected product is Hudson, which I've tried a short time ago.
Installing on a separate server was a little more trickier than on my machine, on which I already had a fully working and customized version of NetBeans. Anyway, I was able to install and configure a bunch of features, e.g. access control and e-mail notification. I have also installed some plugins, like the Task Scanner plugin and the Violations plugin, configured to use PMD after quite a struggle - at least now I know something more about how NetBeans stores informations about libraries and build variables. More on this, including my temporary selection of rules, will follow.

Don't worry about the many broken builds, the project actually consists of a single class with a test class, and all the errors helped me experimenting :-)
Installing on a separate server was a little more trickier than on my machine, on which I already had a fully working and customized version of NetBeans. Anyway, I was able to install and configure a bunch of features, e.g. access control and e-mail notification. I have also installed some plugins, like the Task Scanner plugin and the Violations plugin, configured to use PMD after quite a struggle - at least now I know something more about how NetBeans stores informations about libraries and build variables. More on this, including my temporary selection of rules, will follow.

Don't worry about the many broken builds, the project actually consists of a single class with a test class, and all the errors helped me experimenting :-)
Etichette:
Continuous Integration,
Hudson,
PMD
Subscribe to:
Posts (Atom)