一、基础知识
PMD是一种分析Java代码错误的工具。与其他分析工具不同的是,PMD通过静态分析获知代码错误。也就是说,在不运行Java程序的情况下报告错误。PMD附带了许多可以直接使用的规则,利用这些规则可以找出Java源程序的许多问题,例如没有用到的变量、多余的变量创建操作、空的catch块,等等。此外,用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范。
PMD是一种分析Java代码错误的工具。与其他分析工具不同的是,PMD通过静态分析获知代码错误。也就是说,在不运行Java程序的情况下报告错误。PMD附带了许多可以直接使用的规则,利用这些规则可以找出Java源程序的许多问题,例如没有用到的变量、多余的变量创建操作、空的catch块,等等。此外,用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范。
PMD扫描java代码并寻找潜在的如下问题:
1.可能的bug - 空try/catch/finally/switch语句
2.无效代码 -未使用的变量,参数和私有方法
3.非最佳的代码 - 较耗费资源的String/StringBuffer用法
4.过于复杂的表达式 - 不必要的if语句,或应该为while的for循环
5.重复代码 - 复制/粘贴代码意味着复制/粘贴bug
(2)
PMD各规则:
如:
C:\tools\pmd-4.1\bin>pmd C:\project\***\src html>a.html rulese
ts/unusedcode.xml,rulesets/basic.xml
又如:
C:\Documents and Settings\904031\桌面\findBugs+PMD\pmd-4.2.5\bin>
pmd F:\s2is\dm\dm\java xml>c:\1.xml rulesets/unusedcode.xml
PMD各规则:
如:
C:\tools\pmd-4.1\bin>pmd C:\project\***\src html>a.html rulese
ts/unusedcode.xml,rulesets/basic.xml
又如:
C:\Documents and Settings\904031\桌面\findBugs+PMD\pmd-4.2.5\bin>
pmd F:\s2is\dm\dm\java xml>c:\1.xml rulesets/unusedcode.xml
PMD 包含 16 个规则集,涵盖了 Java 的各种常见问题,其中一些规则要比其他规则更有争议:
基本(rulesets/basic.xml)—— 规则的一个基本合集,可能大多数开发人员都不认同它: catch 块不该为空,无论何时重写 equals(),都要重写 hashCode(),等等。
基本(rulesets/basic.xml)—— 规则的一个基本合集,可能大多数开发人员都不认同它: catch 块不该为空,无论何时重写 equals(),都要重写 hashCode(),等等。
命名(rulesets/naming.xml)—— 对标准 Java 命令规范的测试:变量名称不应太短;方法名称不应过长;类名称应当以小写字母开头;方法和字段名应当以小写字母开头,等等。
未使用的代码(rulesets/unusedcode.xml)—— 查找从未使用的私有字段和本地变量、执行不到的语句、从未调用的私有方法,等等。
设计(rulesets/design.xml)—— 检查各种设计良好的原则,例如: switch 语句应当有 default 块,应当避免深度嵌套的 if 块,不应当给参数重新赋值,不应该对 double 值进行相等比较。
导入语句(rulesets/imports.xml)—— 检查 import 语句的问题,比如同一个类被导入两次或者被导入 java.lang 的类中。
JUnit 测试(rulesets/junit.xml)—— 查找测试用例和测试方法的特定问题,例如方法名称的正确拼写,以及 suite() 方法是不是 static 和 public。
字符串(rulesets/string.xml)—— 找出处理字符串时遇到的常见问题,例如重复的字符串标量,调用 String 构造函数,对 String 变量调用 toString() 方法。
括号(rulesets/braces.xml)—— 检查 for、 if、 while 和 else 语句是否使用了括号。
代码尺寸(rulesets/codesize.xml)—— 测试过长的方法、有太多方法的类以及重构方面的类似问题。
Javabean(rulesets/javabeans.xml)—— 查看 JavaBean 组件是否违反 JavaBean 编码规范,比如没有序列化的 bean 类。
终结函数(finalizer)—— 因为在 Java 语言中, finalize() 方法不是那么普遍(我上次编写这个代码也经是好多年前的事了),所以它们的使用规则虽然很详细,但是人们对它们相对不是很熟悉。这类检查查找 finalize() 方法的各种问题,例如空的终结函数,调用其他方法的 finalize() 方法,对 finalize() 的显式调用,等等。
克隆(rulesets/clone.xml)—— 用于 clone() 方法的新规则。凡是重写 clone() 方法的类都必须实现 Cloneable, clone() 方法应该调用 super.clone(),而 clone() 方法应该声明抛出 CloneNotSupportedException 异常,即使实际上没有抛出异常,也要如此。
耦合(rulesets/coupling.xml)—— 查找类之间过度耦合的迹象,比如导入内容太多;在超类型或接口就已经够用的时候使用子类的类型;类中的字段、变量和返回类型过多等。
严格的异常(rulesets/strictexception.xml)—— 针对异常的测试:不应该声明该方法而抛出 java.lang.Exception 异常,不应当将异常用于流控制,不应该捕获 Throwable,等等。
有争议的(rulesets/controversial.xml)—— PMD 的有些规则是有能力的 Java 程序员可以接受的。但还是有一些争议。这个规则集包含一些更有问题的检验,其中包括把 null 赋值给变量、方法中有多个返回点,以及从 sun 包导入等。
日志(rulesets/logging-java.xml)—— 查找 java.util.logging.Logger 的不当使用,包括非终状态(nonfinal)、非静态的记录器,以及在一个类中有多个记录器。
(3)
PMD各种显示器:
PMD comes with 4 differents type of renderers:
1.text, which does a basic text ouput of pmd's report;
2.xml, which format as XML the report;
3.html, which format the result as a very basic HTML page;
4.nicehtml, which is "better" html view of the result. As this feature use an XSLT transformation, it also possible to override the default stylesheet using the -xslt parameter.
如:
java net.sourceforge.pmd.PMD /path/to/source nicehtml basic,imports,unusedcode -xslt my-own-stylesheet.xsl
2.xml, which format as XML the report;
3.html, which format the result as a very basic HTML page;
4.nicehtml, which is "better" html view of the result. As this feature use an XSLT transformation, it also possible to override the default stylesheet using the -xslt parameter.
如:
java net.sourceforge.pmd.PMD /path/to/source nicehtml basic,imports,unusedcode -xslt my-own-stylesheet.xsl
(3)
错误级别:
PMD priority 1 -> severity error, priority high
PMD priority 2 -> severity error, priority normal
PMD priority 3 -> severity warning, priority high
PMD priority 4 -> severity warning, priority normal
PMD priority 5 -> severity information, priority normal
即:
PMD的优先级1 - “严重的错误,优先高
PMD的优先级2 - “严重的错误,优先正常
PMD的优先3 - “严重警告,优先高
PMD的优先4 - “严重警告,优先正常
PMD的优先5 - “严重的信息,优先正常
错误级别:
PMD priority 1 -> severity error, priority high
PMD priority 2 -> severity error, priority normal
PMD priority 3 -> severity warning, priority high
PMD priority 4 -> severity warning, priority normal
PMD priority 5 -> severity information, priority normal
即:
PMD的优先级1 - “严重的错误,优先高
PMD的优先级2 - “严重的错误,优先正常
PMD的优先3 - “严重警告,优先高
PMD的优先4 - “严重警告,优先正常
PMD的优先5 - “严重的信息,优先正常
即使是PMD priority 1,不意味着代码出错,而是代码不规范。如:
static final的变量非全部大写。
static final sysLoger --- static final SYSLOGER
static final的变量非全部大写。
static final sysLoger --- static final SYSLOGER
----------------------------------------
pmd检测代码且生成html检测报告
pmd检测代码且生成html检测报告
1.下载PMD压缩包
最新pmd4.2.5.zip
2.解压
3.创建如下脚本文件(checkAll.bat),放置在解压后的bin目录下:
@echo off
rem author:hwj 2010-01-27
rem 要检查的文件和路径
set filepath=C:\12
set filepath=C:\12
rem 报告输出的路径
set reportpath=c:\code-check-report\
set reportpath=c:\code-check-report\
rem 获取当前年月日和时分秒
set nowTime=%DATE:~0,10%" "%TIME:~1,7%
set nowTime=%DATE:~0,10%" "%TIME:~1,7%
rem 替换:为-
set nowTime=%nowtime::=-%
set nowTime=%nowtime::=-%
rem 合成报告文件路径名
set outfile=%reportpath%%nowtime%.html
set outfile=%reportpath%%nowtime%.html
rem 指定输出rendener
rem set xslt="../etc/xslt/corley-pmd-report.xslt"
rem set xslt="../etc/xslt/only-prio1.xslt"
rem set xslt="../etc/xslt/pmd-report.xslt"
rem set xslt="../etc/xslt/only-prio1.xslt"
set xslt="../etc/xslt/wz-pmd-report.xslt"
rem set xslt="../etc/xslt/corley-pmd-report.xslt"
rem set xslt="../etc/xslt/only-prio1.xslt"
rem set xslt="../etc/xslt/pmd-report.xslt"
rem set xslt="../etc/xslt/only-prio1.xslt"
set xslt="../etc/xslt/wz-pmd-report.xslt"
rem 指定检查规则,这里包括了官方推出的java的所有规则
set ruleset="rulesets/internal/all-java.xml"
rem 执行检查并输出报告
pmd %filepath% nicehtml %ruleset% -xslt %xslt% -reportfile %outfile%
pmd %filepath% nicehtml %ruleset% -xslt %xslt% -reportfile %outfile%
以上脚本要设置的只有
filepath,reportPath.
生成html,如下:
----------------------------------------
把pmd集成到ant中。
把pmd集成到ant中。
1.(可选)将pmd的lib下的jar文件都copy到项目的build目录下的pmd目录中。此处直接设置为pmd的lib目录
2.打开build.xml,添加如下部分:--此处,直接新建一个文件checkAll.xml
<project name="pmd" default="pmd" basedir="../">
<path id="pmd.classpath">
<pathelement location="${basedir}/"/>
<fileset dir="lib/">
<include name="*.jar"/>
</fileset>
</path>
<project name="pmd" default="pmd" basedir="../">
<path id="pmd.classpath">
<pathelement location="${basedir}/"/>
<fileset dir="lib/">
<include name="*.jar"/>
</fileset>
</path>
<target name="pmd">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd.classpath"/>
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd.classpath"/>
<pmd shortFilenames="true">
<ruleset>unusedcode</ruleset>
<ruleset>basic</ruleset>
<ruleset>imports</ruleset>
<ruleset>unusedcode</ruleset>
<ruleset>basic</ruleset>
<ruleset>imports</ruleset>
<formatter type="html" toFile="pmd_report.html" toConsole="true"/>
<fileset dir="C:\12">
<include name="**/*.java"/>
</fileset>
</pmd>
</target>
</project>
<include name="**/*.java"/>
</fileset>
</pmd>
</target>
</project>
其中path部分是定义pmd所需要的jar的目录为pmd.classpath,${basedir}就是项目所在目录,
target部分就是执行pmd的部分,taskdef定义了执行该任务的类是net.sourceforge.pmd.ant.PMDTask,其类路径为pmd.classpath。pmd 部分是pmd的执行设置,<ruleset>指定其检查规则,formatter是结果输出文件。fileset是被pmd检查的文件目标路径。
保存checkAll.xml之后,可以用ant -buidlfile checkAll.xml 来执行检查.
----------------------------------------
把pmd集成到eclipse中。
只须将此包解压:pmd-eclipse-1.8.0.zip-->放于eclipse中的plugins中,重启eclipse-->右键选择项目-->PMD-->选择第一个选项toggle PMD nature-->在eclipse中的question中会生成PMD的检查结果-->若要消失,则再选择项目-->PMD-->选择第一个选项toggle PMD nature即可。
把pmd集成到eclipse中。
只须将此包解压:pmd-eclipse-1.8.0.zip-->放于eclipse中的plugins中,重启eclipse-->右键选择项目-->PMD-->选择第一个选项toggle PMD nature-->在eclipse中的question中会生成PMD的检查结果-->若要消失,则再选择项目-->PMD-->选择第一个选项toggle PMD nature即可。