静态分析工具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 自带了很多代码规范的规则,还可以自定义规则,我们可以把这些规则整合到一起,按照我们的需求进行代码检查。
<!--  使用整个strings规则集  -->
   < rule  ref ="rulesets/strings.xml" />
<!--  使用某个规则集里的某个规则  -->
   < rule  ref ="rulesets/unusedcode.xml/UnusedLocalVariable" />
   <!--  指定某个规则集里的某个规则的优先级  -->
< rule  ref ="rulesets/basic.xml/EmptyCatchBlock"  message ="Must handle exceptions" >
     < 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

Migrating JDK 版本移植的规则,如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  ="Must handle exceptions"  > 
          <  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) 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值