静态分析工具PMD使用总结

PMD(http://pmd.sourceforge.net/

简介:PMD扫描java源代码,查找潜在的问题,如:

可能的bugs,如空的try/catch/finally/switch声明

死亡的代码,没有使用的本地变量,参数和私有方法

不合标准的代码,如String/StringBuffer用法

过于复杂的表达式,如不必要的if表达式

重复的代码,拷贝、粘贴的代码

PMD的含义,如

Project Mess Detector

Project Monitoring Directives

Project Meets Deadline

Programming Mistake Detector…

用法:可以在命令行下执行,如

pmd c:\Test.java xml rulesets/unusedcode.xml

也可以使用IDE的插件,如Eclipse、IDEA、JBuilder、JCreator等等

这里主要介绍Ant里的调用,

下面是主要的Ant配置信息
< path id ="pmd.path" >
< fileset dir ="${lib.dir}/pmd-3.8" >
< include name ="**/*.jar" />
fileset >
path >
< taskdef name ="pmd" classname ="net.sourceforge.pmd.ant.PMDTask" classpathref ="pmd.path" />
< taskdef name ="cpd" classname ="net.sourceforge.pmd.cpd.CPDTask" classpathref ="pmd.path" />
< target name ="pmd" >
< pmd shortFilenames ="true" >
< ruleset >rulesets/favorites.xml ruleset >
< formatter type ="html" toFile ="d:\foo.html" toConsole ="false" />
< fileset dir ="${src.dir}" >
< include name ="**/*.java" />
fileset >
pmd >
target >
< target name ="cpd" >
< cpd minimumTokenCount ="100" outputFile ="d:/cpd.txt" >
< fileset dir ="${src.dir}" >
< include name ="**/*.java" />
fileset >
cpd >
target >

自定义规则:

有两个办法来自定义规则,可以编写java类和编写XPath,编写java类的一般步骤是,先确定要查找的代码形式,利用PMD自带的designer.bat工具查看AST(抽象语法树),然后编写规则类(继承net.sourceforge.pmd.AbstractRule),然后编写一个ruleset的XML文件,最后就可以运行PMD进行检查。编写XPath比编写java类要容易些,但也需要掌握AST的含义,利用designer.bat工具可以查看AST,比如//ClassBody [count(//VariableDeclarator[../Type/Name[@Image='Logger']])>1],这个表达式就是查找类的代码里是否声明了多个Logger,然后编写一个ruleset的XML文件,最后运行PMD进行检查。这里是一个ruleset的XML文件的例子。

自定义规则集合:

PMD自带了很多代码规范的规则,还可以自定义规则,我们可以把这些规则整合到一起,按照我们的需求进行代码检查。

< rule ref ="rulesets/strings.xml" />

< rule ref ="rulesets/unusedcode.xml/UnusedLocalVariable" />

< rule ref ="rulesets/basic.xml/EmptyCatchBlock" message ="Musthandleexceptions" >
< priority >2 priority >
rule >

< rule ref ="rulesets/braces.xml" >
< exclude name ="WhileLoopsMustUseBracesRule" />
rule >

最后,我们运行PMD的时候就可以指定这个ruleset文件。

自带规则的介绍:

PMD自带了很多规则集合,并且分类写入不同的ruleset文件,如

Basic包含每人都必须遵守的代码最佳实践,如EmptyCatchBlock

Braces关于条件分支的规则,如IfStmtsMustUseBraces

Code Size关于代码大小的规则,如方法的长度,参数的长度,属性的个数等

Clone克隆实现的规则,如是否有super.clone()

Controversial一些有争议的规则,如UnnecessaryConstructor不必要的构造器

Coupling对象连接有关的规则

Design可以检查有问题的设计,如SwitchStmtsShouldHaveDefault

Finalizers使用finalizers时需遵循的规则,如FinalizeOnlyCallsSuperFinalize

Import Statements和import有关的规则,如DuplicateImports重复import

J2EE唯一规则UseProperClassLoader,class.getClassLoader()可能不正确,用

Thread.currentThread().getContextClassLoader()代替

Javabeans和javabean规范有关的规则,有BeanMembersShouldSerialize属性必须

序列化和MissingSerialVersionUID缺少序列化ID

JUnit Tests和JUnit测试有关的,如JUnitSpelling拼写检查等

Logging (Java)检查Logger的一些错误用法,如MoreThanOneLogger多个Logger

Logging (Jakarta)使用Jakarta Logger的一些规则,有UseCorrectExceptionLogging

异常处理不当和ProperLogger是否正确定义Logger

MigratingJDK版本移植的规则,如ReplaceVectorWithList用List代替Vector

Naming和命名有关的规则,名称太短或太长,命名的约定等

Optimizations优化性能的一些规则,如LocalVariableCouldBeFinal本地变量如果

只赋值一次,则应该声明为final

Strict Exceptions比较严格的异常处理方针,如AvoidCatchingThrowable

Strings使用String和StringBuffer时应遵守的规则,如StringToString

Sun Security编写安全的代码,有MethodReturnsInternalArray直接返回内部的数组,

更安全的做法是返回一个拷贝和ArrayIsStoredDirectly

Unused Code检查未使用的代码,如UnusedPrivateField未使用的私有属性

Java Server Pages编写jsp的一些方针,如NoLongScripts

Java Server Faces编写jsf的一些方针,有DontNestJsfInJstlIteration,在Jsf

里使用jstl的标签

PMD里面还有一个写好的ruleset文件,在pmd-3.8.jar里面的rulesets文件夹下,名称是favorites.xml,以下是主要部分:

< rule ref ="rulesets/basic.xml" />
< rule ref ="rulesets/basic.xml/EmptyCatchBlock" message ="Musthandleexceptions" >
< priority >2 priority >
rule >
< rule ref ="rulesets/unusedcode.xml" />
< rule ref ="rulesets/braces.xml/WhileLoopsMustUseBraces" />
< rule ref ="rulesets/braces.xml/ForLoopsMustUseBraces" />
< rule ref ="rulesets/design.xml/SimplifyBooleanReturns" />
< rule ref ="rulesets/design.xml/SwitchStmtsShouldHaveDefault" />
< rule ref ="rulesets/strings.xml/StringToString" />
< rule ref ="rulesets/strings.xml/StringInstantiation" />
< rule ref ="rulesets/controversial.xml/UnnecessaryConstructor" />
< rule ref ="rulesets/controversial.xml/NullAssignment" />
< rule ref ="rulesets/controversial.xml/UnusedModifier" />
< rule ref ="rulesets/codesize.xml/CyclomaticComplexity" >
< properties >< property name ="reportLevel" value ="5" /> properties >
rule >

其它事项:

1.可以使用JDK1.5的声明@SuppressWarnings(""),禁止PMD的警告。

2.可以使用//NOPMD来标记行或块代码,禁止PMD警告。

3.有两种方法自定义Rule,编写java类和编写XPath。

4.PMD提供了多种IDE的插件来运行PMD。

参考文档:

PMD官方文档(http://pmd.sourceforge.net/)

OnJava上一篇文档(http://www.onjava.com/pub/a/onjava/2003/04/09/pmd_rules.html

代码静态分析(http://blog.donews.com/foxgem/archive/2005/04/23/347444.aspx)

你可能感兴趣的:(静态分析工具PMD使用总结)