提高代码的质量,除了要提高逻辑上的控制以及业务流程的理解外,代码本身也存在提高的空间,例如一些潜在的问题可以很早的就避免。类似于编码规范上的内容,如果全靠编码人员进行自行检查,那么无疑需要很大的工作量,如果可以使用代码的静态检查工具进行检查的话,那么将大大的提高编码的效率。
本文是提高代码质量系列文章的第一篇,主要介绍了如何使用pmd工具进行代码的自动化检查,以规避一些潜在的问题并找出代码的逻辑错误。
1. 什么是PMD?
PMD是一个代码检查工具,用于检查Java源代码,以便发现如下的潜在问题:
® 潜在的bug:空的try/catch/finally/switch语句
® 未使用的代码:未使用的局部变量、参数、私有方法等
® 可选的代码:String/StringBuffer的滥用
® 复杂的表达式:不必须的if语句、可以使用while循环完成的for循环
® 重复的代码:拷贝/粘贴代码意味着拷贝/粘贴bugs
可以在以下地址下载pmd,并且可以在规则集索引页面查看所有规则的一个预览。
同时,pmd已经与JDeveloper、Eclipse、jEdit、JBuilder、BlueJ、CodeGuide、NetBeans、Sun Java Studio Enterprise/Creator、IntelliJ IDEA、TextPad、Maven、Ant、Gel、JCreator以及Emacs集成在一起。
2. 在Eclipse中安装PMD插件
PMD可以作为插件集成到很多流行的IDE中,很多的插件中都包含了PMD的jar文件,这个jar文件中包含了规则集。所以虽然一些插件中使用rulesets/unusedcode.xml来作为参数引用规则集,但是实际上是使用getResourceAsStream()方法来从PMD的jar文件中加载。
由于Eclipse是比较流行的开源Java/J2EE开发IDE,所以本文主要介绍如何在Eclipse中使用PMD工具进行代码的检查。
安装Eclipse的PMD插件的过程如下:
® 启动Eclipse
® 选择Help-->Software Updates-->Find and Install
® 选择Next,选择New remote site
® 在Name框中输入PMD,URL框中输入http://pmd.sf.net/eclipse
® 在之后的对话框中一直点击下一步或者接受协议,完成Eclipse的PMD插件的安装
也可以通过下载最新的zip文件按,然后执行上述过程,只是使用New locale site来代替New remote site,并使用下载的zip文件。
可以通过Windows-->Preferences来配置PMD。
通过右键一个项目,然后选择PMD-->Check node with PMD,即可使用PMD工具检查代码。如果要进行重复代码检测,那么右键一个项目后,选择PMD-->Find suspect cut and paste。检查结果会放在reports目录下,文件名为cpd-report.txt。
可以通过使用Eclipse的帮助系统来查看PMD插件的文档。
在安装完更新后,如果发生了一个异常,例如”java.lang.RuntimeException: Could not find that class xxxx”,这时试着删除workspace中的.metadata/plugins/net.sourceforge.pmd.eclipse目录下的ruleset.xml文件。
3. 最佳实践
选择合适的规则
运行所有的规则集中的规则会产生非常多的冲突,这些冲突中的很多是不重要的。在这么多的冲突中寻找你关心的部分结果就没有什么效率可言了。
所以需要从明显的规则集,也就是说必须要改的地方开始是比较好的一个选择,例如只是运行unusedcode检查,然后修改没有使用的局部变量和成员变量。然后运行基本的检查,修改所有的空语句,例如if语句等。最后可以执行与设计相关的或者存在一定争议的规则集,或者自定义的规则集。
PMD规则是可以定制的
一般来说,选择那些可以利用的规则,而忽略或者禁止不需要的警告,毕竟PMD只是代码检查工具。
推荐使用PMD IDE插件
比起在HTML报告和IDE工具之间进行重复的切换,使用IDE的PMD插件更加简单易用。很多IDE插件都具有选中规则冲突后,就可以跳转到该行代码的功能,这样修改代码会变得更加的容易。
4. 安装并从命令行运行PMD
下载PMD后,将其解压缩到本地目录,例如PMD_HOME。
基本使用
$PMD_HOME/bin/pmd.bat命令的使用帮助如下:
pmd的必要参数如下:
1) Java源代码文件或者目录,可以是文件,目录,jar文件,zip文件等
2) 报告的格式
3) 规则集文件的名字或者以逗号分隔的一串规则集文件的名字
例如:
c:/> java -jar pmd-4.2.1.jar c:/my/source/code html unusedcode
一些可以加载必须参数前面或者后面的可选参数如下:
-debug: 打印debug日志信息
-targetjdk: 指定目标源代码的版本- 1.3, 1.4, 1.5, 1.6 or 1.7;
默认是1.5
-cpus: 指定创建的线程数
-encoding: 指定PMD检查的代码的编码方式
-excludemarker: 指定PMD需要忽略的行的标记,默认为NOPMD
-shortnames: 在报告中显示缩短的文件名
-linkprefix: HTML源文件的路径,只是为了HTML显示
-lineprefix: 自定义的锚,用于影响源文件中的行,只是用于HTML显示
-minimumpriority: 规则的优先级限制,低于优先级的规则将不被使用
-nojava: 不检查java文件,默认是检查java文件
-jsp: 检查JSP/JSF文件,默认不检查
-reportfile: 将报告输出到文件,默认是打印在控制台
-benchmark: 输出一个基准清单,默认输出到控制台
-xslt: 覆盖默认的xslt
-auxclasspath: 指定源代码文件使用的类路径
例如在windows系统中,例子如下:
c:/> java -jar pmd-4.2.1.jar c:/my/source/code text unusedcode,imports -targetjd
k 1.5 -debug
c:/> java -jar pmd-4.2.1.jar c:/my/source/code xml basic,design -encoding UTF-8
c:/> java -jar pmd-4.2.1.jar c:/my/source/code html typeresolution -auxclasspath
commons-collections.jar;derby.jar
c:/> java -jar pmd-4.2.1.jar c:/my/source/code html typeresolution -auxclasspath
file:///C:/my/classpathfile
当出现违反规则的代码时,打印在控制台上的信息如下:
C:/tmp/pmd-4.2.1/pmd/bin>pmd c:/data/pmd/pmd/test-data/Unused1.java xml rulesets/unusedcode.xml
<?xml version="1.0"?><pmd>
<file name="c:/data/pmd/pmd/test-data/Unused1.java">
<violation line="5" rule="UnusedLocalVariable">
Avoid unused local variables such as 'fr'
</violation>
</file></pmd>
也可使使用如下的方法(不使用批处理文件)运行PMD:
C:/data/pmd/pmd>java -cp lib/pmd-4.2.1.jar;lib/jaxen-1.1.1.jar;lib/asm-3.1.jar
net.sourceforge.pmd.PMD
c:/j2sdk1.4.1_01/src/java/lang xml
rulesets/imports.xml
高级使用
除了将输出结果作为控制台、文本文件、xml文件、html文件输出外,还可以使用xslt将输出结果转换成任意的文件格式。
还可以使用缩写名来使用内置的规则名,例如
java net.sourceforge.pmd.PMD /path/to/source text basic,imports,unusedcode
5. 总结
虽然使用命令行是原始的方法,可以生成任意格式的报告,但是为了更好,更快的修改代码能够存在的问题,使用插件的方式无疑可以提高效率,所以还是建议使用插件。
PMD对各种IDE都提供了插件,笔者一直使用Eclipse,所以就将Eclispe作为例子进行了插件的安装和简单实用,关于其他的IDE环境下PMD的安装及使用,请参考相关文档。