`
zhb8015
  • 浏览: 398281 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Group-logo
Spring Roo杂谈
浏览量:0
社区版块
存档分类
最新评论

用PMD自动执行Java代码静态分析

 
阅读更多

 一、基础知识

  PMD是一种分析Java代码错误的工具。与其他分析工具不同的是,PMD通过静态分析获知代码错误。也就是说,在不运行Java程序的情况下报告错误。PMD附带了许多可以直接使用的规则,利用这些规则可以找出Java源程序的许多问题,例如没有用到的变量、多余的变量创建操作、空的catch块,等等。此外,用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范。例如,你可以编写一个规则,要求PMD找出所有创建Thread和Socket对象的操作。

  最初,PMD是为了支持Cougaar项目而开发的。Cougaar是美国国防高级研究计划局(Defense Advanced Research Projects Agency,DARPA)的一个项目。DARPA开放了PMD的源代码,所以PMD被发布到了SourceForge网站上。不久前,PMD的下载次数就超过了14000次,页面浏览次数超过了130000次。更重要的是,在源代码开放作者的努力下,越来越多的PMD规则和IDE插件被开发出来,然后加入到了PMD的核心项目之中。

  你可以从PMD的网站下载PMD的二进制版本,或下载带源代码的版本,下载得到的都是ZIP文件。假设你下载了二进制版本,先把它解压缩到任意一个目录。接下来怎么做,就要看你准备怎么用它——最简单的,如果要在一个Java源代码目录中运行PMD,只需直接在命令行上运行下面的命令:

C:/data/pmd/pmd>java -jar lib/pmd-1.02.jar c:/j2sdk1.4.1_01/src/java/util 
   text rulesets/unusedcode.xml

  输出结果类如:

c:/j2sdk1.4.1_01/src/java/util/AbstractMap.java 650 
    Avoid unused local variables such as 'v'    
c:/j2sdk1.4.1_01/src/java/util/Date.java        438  
    Avoid unused local variables such as 'millis'

  除了直接在命令行上运行PMD之外,还可以通过Ant、Maven或者各种集成开发环境(IDE)运行PMD,例如jEdit、Netbeans、Eclipse、Emacs、IDEAJ和JBuilder等。

  二、内建规则

  PMD本身就附带了许多规则。下面是几个例子。

没有用到的代码显然是应该被清除的。
public class Foo {
   // 下面这个实例变量没有用到
   private List bar = new ArrayList(500);
}
如果用一个接口也能达到同样的目标,为什么要返回一个具体的类?例如,下例可以改用List接口。
public ArrayList getList() {
   return new ArrayList();
}
当if的条件为真时,if代码块其实不做任何事情。下面这段代码其实可以写得更加简洁一些。
public void doSomething(int y) {
   if (y >= 2) { 
   } else {
      System.out.println("Less than two");
   }
}
为什么要创建一个新的String对象?只要改用String x="x"就可以了。
String x = new String("x");

  PMD还包含其他许多内建规则,但从上面几个例子已经可以看出PMD的基本工作方式。只要定义适当的静态规则,PMD就可以象一个富有经验的程序员那样,帮你指出代码存在的问题。

  三、工作原理

  PMD的核心是JavaCC解析器生成器。PMD结合运用JavaCC和EBNF(扩展巴科斯-诺尔范式,Extended Backus-Naur Formal)语法,再加上JJTree,把Java源代码解析成抽象语法树(AST,Abstract Syntax Tree)。显然,这句话不那么好懂,且看下文具体说明。

  从根本上看,Java源代码只是一些普通的文本。不过,为了让解析器承认这些普通的文本是合法的Java代码,它们必须符合某种特定的结构要求。这种结构可以用一种称为EBNF的句法元语言表示,通常称为“语法”(Grammar)。JavaCC根据语法要求生成解析器,这个解析器就可以用于解析用Java编程语言编写的程序。

  不过实际运行中的PMD还要经过JJTree的一次转换。JJTree是一个JavaCC的插件,通过AST扩充JavaCC生成的解析器。AST是一个Java符号流之上的语义层。有了JJTree,语法分析的结果不再是“System, ., out, ., . println”之类的符号序列,而是一个由对象构成的树型层次结构。例如,下面是一段简单的Java代码以及与之对应的AST。

Java源代码:
public class Foo {
    public void bar() {
        System.out.println("hello world");
    }
}
对应的抽象语法树
CompilationUnit
 TypeDeclaration
  ClassDeclaration
   UnmodifiedClassDeclaration
    ClassBody
     ClassBodyDeclaration
      MethodDeclaration
       ResultType
       MethodDeclarator
        FormalParameters
       Block
        BlockStatement
         Statement
          StatementExpression
           PrimaryExpression
            PrimaryPrefix
             Name
            PrimarySuffix
             Arguments
              ArgumentList
               Expression
                PrimaryExpression
                 PrimaryPrefix
                  Literal

  四、编写规则

  前面我们看到了Java源代码以及与之对应的对象层次结构。下面我们就要利用这些对象编写PMD规则检查代码存在的问题。

  一般地,一个PMD规则可以看成一个Visitor,它遍历AST,寻找多个对象之间的一种特定模式,这种模式表示代码存在的问题。问题模式可能简单也可能复杂,简单的如查找代码中是否包含new Thread关键词,复杂的如确定一个类是否正确覆盖了equals和hashcode。

  下面是一个寻找空if语句的简单PMD规则。

//扩展AbstractRule,以启用Visitor模式
public class EmptyIfStmtRule extends AbstractRule implements Rule {
   //当源代码中出现一个Block,下面的方法被调用
   public Object visit(ASTBlock node, Object data){
      //如果父节点是一个if语句且代码块里面没有任何内容
      if ((node.jjtGetParent().jjtGetParent() instanceof ASTIfStatement) 
         && node.jjtGetNumChildren()==0) {
         //肯定代码存在问题。把一个RuleViolation加入到Report。
         RuleContext ctx = (RuleContext)data;
         ctx.getReport().addRuleViolation(createRuleViolation(ctx,
            node.getBeginLine()));
      }
      //继续检查树的下一个节点
      return super.visit(node, data);
   }
}

  也许你不能一下子掌握这段代码,其实它的思路还是比较简单的:

  #扩展AbstractRule基类。

  #声明一个“钩子”,一旦我们感兴趣的节点出现,它就会被调用(称为“回调”)。在上面的例子中,我们要求在每一个ASTBlock出现时得到通知,所以声明visit(ASTBlock node, Object data)。

  #在回调函数中,判断是否出现了我们正在检查的问题。本例我们检查是否存在空的if块,所以先判断当前是否在ASTIfStatement之内,然后判断它是否有子节点。

  当然,我们还可以按照另一种方法进行检查:声明一个要求检查ASTIfStatement的回调函数,然后在回调函数中检查是否存在子节点。

  五、配置规则

  写好自定义规则之后,接下来要把它加入到某个PMD规则集。所谓PMD规则集,就是由一组PMD规则构成的集合。每个PMD规则集由一个XML文件定义,下面是一个PMD规则的配置信息的例子:

<rule name="EmptyIfStmt"
   message="避免使用空的if语句"
   class="net.sourceforge.pmd.rules.EmptyIfStmtRule">
   <description>
      找到空的if语句:if检查了条件,但if块里面没有任何内容。
   </description>
   <priority>3</priority>
   <example>
      <![CDATA[
         if (absValue < 1) {
            // not good
         }
      </XMLCDATA>
   </example>
</rule>

  可以看出,规则配置文件包含了许多有用的信息。要运行新添加的规则,只需把规则集XML文件和Java源代码文件放入CLASSPATH,然后运行PMD。

  结束语:本文介绍了PMD如何在不编译代码的情况下分析和寻找代码存在的问题,通过几个简单的例子了解了EBNF语法、JavaCC和AST,以及如何用PMD检查代码存在的问题、如何编写和运用定制PMD规则等。愿PMD能够助你一臂之力!

  参考:

  PMD home page

  PMD Scoreboard (SourceForge)

  PMD Scoreboard (Jakarta)

  How to write a PMD rule

  DARPA home page

  Cougaar home page

  JUnit home page

  Maven home page

  JavaCC/JJTree home page

分享到:
评论

相关推荐

    pmd-4.2.5 Java代码检测

    **PMD 4.2.5 - Java代码检测详解** PMD是一款强大的静态代码分析工具,主要用于检测Java源代码中的潜在问题、代码异味(Code Smell)和编程错误。PMD 4.2.5是该工具的一个版本,它旨在帮助开发者提升代码质量,预防...

    4 种主流 Java 静态代码分析工具

    **简介**:FindBugs是一款由马里兰大学开发的静态分析工具,它能够检测Java程序中的潜在缺陷。通过分析字节码,FindBugs可以识别出可能导致错误的行为。 **功能**: - **缺陷检测**:基于预定义的缺陷模式,检测...

    java代码静态检查工具

    Java代码静态检查工具是开发过程中不可或缺的一环,它主要用于在编码阶段就发现潜在的问题,提高代码质量,减少错误。在Android Studio这样的集成开发环境中,我们可以方便地集成这些工具,使得静态检查成为日常开发...

    java静态检查 pmd

    在构建脚本中添加PMD插件,并配置相关参数,可以在每次构建时自动执行代码检查。 PMD还提供了额外的功能,如: - CPD (Copy-Paste Detector):这是一个内置的代码重复检测工具,可以帮助找出代码中的重复块,避免...

    PMD对java程序分析实验报告

    2. **IDE集成**:在IDE中,通常可以在项目设置中配置PMD插件,设置规则集,并在保存代码时自动运行检查。 **四、PMD规则集** PMD的规则集分为多个类别,如基本(Basic)、设计(Design)、冗余代码(Redundant ...

    Jenkins集成Java 静态代码分析工具调研和引入

    Jtest是一个较为全面的Java代码质量分析工具,它集成了包括静态分析、动态测试和代码覆盖率分析在内的多种功能,但使用它需要购买相应的授权。 ### 工具比较 文章对上述工具进行了分析比较,包括它们的分析对象、...

    四种常用的java代码扫描工具介绍

    1. 帮助程序开发人员自动执行静态代码分析,快速定位代码隐藏错误和缺陷。 2. 帮助代码设计人员更专注于分析和解决代码设计缺陷。 3. 显著减少在代码逐行检查上花费的时间,提高软件可靠性并节省软件开发和测试成本...

    pmd代码检查工具使用

    PMD 是一个静态代码分析工具,主要用于检查 Java 代码的质量和可读性。下面是 PMD 的使用指南,包括安装、运行、规则配置和自定义规则等方面的内容。 安装和运行 PMD 可以通过命令行或在 Eclipse 中安装插件两种...

    静态代码检查插件之pmd

    PMD 是一个开源的静态代码分析工具,主要用于Java语言,但也有对其他语言如JavaScript、 Apex 和 Groovy 的支持。它的主要目标是帮助开发者发现并修复潜在的bug,提高代码质量,遵循最佳实践,并减少代码的复杂性。...

    代码静态检查 PMD findBugs checkStyle

    代码静态检查工具正是为了这一目的而存在的,它们可以帮助开发者在程序运行之前发现潜在的错误和不规范的编程习惯。在本篇文章中,我们将聚焦三个知名的代码静态检查工具:PMD、FindBugs和CheckStyle。 **PMD** PMD...

    Java代码缺陷自动分析工具介绍

    这些工具通过静态分析技术在代码执行前就识别出可能存在的错误和不良编程习惯。本文将重点介绍 FindBugs,同时也会提及 PMD 和 CheckStyle。 **FindBugs** 是一款知名的 Java 字节码静态分析工具,旨在帮助开发者找...

    java代码质量检测工具包含findbug、pmd插件等

    Java代码质量检测是软件开发过程中不可或缺的一环,它有助于提高代码的可读性、可维护性和性能。在Java开发环境中,有许多工具可以帮助我们进行代码质量检测。本篇文章将重点介绍标题和描述中提及的三个主要工具:...

    PMD集成myeclipse及PMD规则说明

    **PMD** 是一个开源的静态代码分析工具,主要用于检测Java源代码中的潜在问题,比如冗余代码、未使用的变量、空捕获块等。它通过应用一系列预定义的规则来帮助开发者提升代码质量,避免潜在的bug,并遵循最佳编程...

    Java代码审查工具

    2. **PMD**:PMD是一个开源的静态代码分析工具,用于检测Java代码中的常见问题,如未使用的变量、空的catch块、无效的if语句等。开发者可以自定义规则,以适应特定的项目需求。 3. **Checkstyle**:这个工具专注于...

    java静态代码分析插件checkstyle的应用

    Java静态代码分析插件Checkstyle在Java开发中的应用是一个重要的质量保证工具,它能帮助开发者遵循编码规范,提高代码的可读性和可维护性。Checkstyle通过对源代码进行检查,指出不符合约定或潜在问题的地方,使得...

    PMD使用说明(内含Jar包)

    PMD是开源的代码质量检查工具,主要用于静态分析Java源代码,找出潜在的编程错误和不良编程习惯。它可以帮助开发者遵循最佳实践,提升代码质量和可维护性。PMD通过定义一系列规则来执行检查,这些规则涵盖了命名规范...

    MyEclipse PMD插件

    MyEclipse PMD插件是Java开发者在Eclipse集成开发环境中常用的一款静态代码分析工具。PMD这个名字来源于“Pattern Matching for Java”,它旨在通过检查源代码中的潜在问题,帮助开发者提高代码质量和遵循最佳实践。...

    Java代码检查工具、测试工具

    FindBugs是一款开源的静态代码分析工具,用于检测Java代码中的潜在错误和不良实践。它通过分析字节码来查找可能的问题,而不是在运行时进行检查,因此可以在早期发现代码中的问题,避免它们成为难以调试的bug。...

    java代码格式化

    总结起来,Java代码格式化是一个涉及编码规范、自动化工具、IDE配置、静态代码分析等多个方面的系统工程。通过合理的配置和工具选择,我们可以确保代码保持一致性和整洁性,从而提高开发效率,促进团队协作,提升...

    pmd-bin-5.0.0.zip

    PMD是开源的源代码分析工具,主要用于检测Java代码中的潜在问题。"pmd-bin-5.0.0.zip"是PMD的一个版本,包含了该工具的可执行文件和其他相关资源。这个版本号表示这是PMD的5.0.0版本,通常每个版本都会有性能改进、...

Global site tag (gtag.js) - Google Analytics