静态分析工具PMD使用说明
目录
静态分析工具PMD使用说明... 1
目录... 2
1. 编写目的... 3
2. PMD简介... 4
3. PMD的安装和运行... 4
3.1安装并从命令行运行PMD. 4
3.2在Eclipse中安装PMD插件运行方式... 6
3.3 使用Ant进行调用... 8
4. 关于PMD规则... 10
5. 编写自定义的PMD规则... 15
6. 结束语... 18
7. 参考资料... 18
1. 编写目的
除了没有良好的培训、文档等有效的机制以外,每个人一套的编码风格,也容易造成新成员对于已有代码的理解不够,甚至出现偏差。
提高代码的质量,除了要提高逻辑上的控制以及业务流程的理解外,代码本身也存在提高的空间,例如一些潜在的问题可以很早的就避免。类似于编码规范上的内容,如果全靠编码人员进行自行检查,那么无疑需要很大的工作量,如果可以使用代码的静态检查工具进行检查的话,那么将大大的提高编码的效率。
本文主要介绍了如何使用pmd工具进行代码的自动化检查,以规避一些潜在的问题并找出代码的逻辑错误。
2. PMD简介
® 潜在的bug:空的try/catch/finally/switch语句
® 可选的代码:String/StringBuffer的滥用
® 复杂的表达式:不必须的if语句、可以使用while循环完成的for循环
® 循环体创建新对象:尽量不要再for或while循环体内实例化一个新对象
@ 资源关闭:Connect,Result,Statement等使用之后确保关闭掉
此外,用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范。例如,你可以编写一个规则,要求PMD找出所有创建Thread和Socket对象的操作。
3. 工作原理
4. PMD的安装和运行
4.1安装并从命令行运行PMD
E:\SoftWare\pmd-bin-4.2.1\pmd-4.2.1\bin>java -jar ..\lib\pmd-4.2.1.jar D:\ebsser
vice\ebsservice\src text rulesets/unusedcode.xml
D:\ebsservice\ebsservice\src\com\sinosoft\service\policy\ebs\SMPolicyInput.java:
51 Avoid unused private fields such as 'logger'.
D:\ebsservice\ebsservice\src\com\sinosoft\service\policy\ebs\SMPolicyShow.java:2
5 Avoid unused private fields such as 'logger'.
D:\ebsservice\ebsservice\src\com\sinosoft\service\policy\ebs\SMQueryPolicyByPoli
cyNo.java:32 Avoid unused local variables such as 'visaStatus'.
D:\ebsservice\ebsservice\src\com\sinosoft\service\policy\ebs\SMQueryPolicyByPoli
cyNo.java:44 Avoid unused local variables such as 'temp'.
D:\ebsservice\ebsservice\src\com\sinosoft\service\policy\ebs\erisk\ESMPolicyInpu
t.java:28 Avoid unused private fields such as 'logger'.
D:\ebsservice\ebsservice\src\com\sinosoft\service\policy\ebs\jrisk\JSMPolicyInpu
t.java:22 Avoid unused private fields such as 'logger'.
-targetjdk: 指定目标源代码的版本- 1.3, 1.4, 1.5, 1.6 or 1.7;
-excludemarker: 指定PMD需要忽略的行的标记,默认为NOPMD
-linkprefix: HTML源文件的路径,只是为了HTML显示
-lineprefix: 自定义的锚,用于影响源文件中的行,只是用于HTML显示
-minimumpriority: 规则的优先级限制,低于优先级的规则将不被使用
-nojava: 不检查java文件,默认是检查java文件
-reportfile: 将报告输出到文件,默认是打印在控制台
c:\> java -jar pmd-4.2.1.jar c:\my\source\code text unusedcode,imports -targetjd
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
4.2在Eclipse中安装PMD插件运行方式
PMD可以作为插件集成到很多流行的IDE中,很多的插件中都包含了PMD的jar文件,这个jar文件中包含了规则集。所以虽然一些插件中使用rulesets/unusedcode.xml来作为参数引用规则集,但是实际上是使用getResourceAsStream()方法来从PMD的jar文件中加载。
由于Eclipse是比较流行的开源Java/J2EE开发IDE,所以本文主要介绍如何在Eclipse中使用PMD工具进行代码的检查。
4.2.1 安装基于Eclipse IDE的插件
® 选择Help-->Software Updates-->Find and Install
® 在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插件的文档。
4.2.2 使用PMD
public static void main(String[] args) {
System.out.println("Hello World!");
以上代码PMD会检查出:catch块中没有内容、if判断块中没有内容、代码中出现System.out.println等警告描述
4.3 使用Ant进行调用
<fileset dir="${lib.dir}/pmd-3.8">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd.path"/>
<taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask" classpathref="pmd.path"/>
<ruleset>rulesets/favorites.xml</ruleset>
<formatter type="html" toFile="d:\foo.html" toConsole="false"/>
<cpd minimumTokenCount="100" outputFile="d:/cpd.txt">
用Ant命令运行build.xml,PMD就会按照你设定好的规则自动执行代码检查了。
5. 关于PMD规则
运行所有的规则集中的规则会产生非常多的冲突,这些冲突中的很多是不重要的。在这么多的冲突中寻找你关心的部分结果就没有什么效率可言了。
所以需要从明显的规则集,也就是说必须要改的地方开始是比较好的一个选择,例如只是运行unusedcode检查,然后修改没有使用的局部变量和成员变量。然后运行基本的检查,修改所有的空语句,例如if语句等。最后可以执行与设计相关的或者存在一定争议的规则集,或者自定义的规则集。
自带规则的介绍: (PMD插件分析代码规则(中文).xls)
PMD 自带了很多规则集合,并且分类写入不同的 ruleset 文件,如
Basic 包含每人都必须遵守的代码最佳实践,如EmptyCatchBlock
Braces 关于条件分支的规则,如IfStmtsMustUseBraces
Code Size 关于代码大小的规则,如方法的长度,参数的长度,属性的个数等
Clone 克隆实现的规则,如是否有super.clone()
Controversial 一些有争议的规则,如UnnecessaryConstructor不必要的构造器
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本地变量如果
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
自定义规则集合:
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文件,在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。
6. 编写自定义的PMD规则
1.了解XPath:http://www.w3.org/TR/xpath
PMD把AST处理成一个符号表,你可以在符号表里面查询一些有用的信息
接着pmd产生一个报表,上面说明了有哪些地方违反了pmd规则
一.用java code,需要了解pmd的api,需要进行深入研究,也常常用于一些比较复杂的pmd规则
二.用xpath,对着产生的AST树,写就行了,上手比较快,写起来也比较简单
在项目中,我们不希望Application的开发人员手动的调用Toplink UnitOfWork的commit,
commitAndResume, commitAndResumeOnFailure'方法,因为每次提交都会映像performa,我们的提交是放在自己编写的framework里面,
在指定的位置提交。所以我们把规则的优先级设置为3. 在eclipse的pmd plugin中,优先级为3会产生一个警告。
1首先将D:"local_lib"pmd-bin-4.2"bin 加到系统环境变量的path中
3左上角source code可以把你写好的java source copy过来主要就在这个java source code基础上不断修正你的pmd规则。
4xpath query:用来编写自定义的xpath expression(先不忙写xpath expression)
5点击go,就会在左下角的Abstract syntax Tree中产生AST,你可以选择AST上的某个节点,左下角的下面一个框中就会出现该节点的一些信息。
6.DFA是pmd4的新功能,用于编写更复杂的pmd规则,不光是某个source code级别了,pmd4使用了asm读取字节码,并作分析,处理类文件之间的依赖性。
在实际使用中,特别是在特定应用中,这个功能是相当有用的。还可以用来简化一些现有的规则。
7根据生成的AST编写xpath expression。对于上文提到的source检查规则编写了一个xpath
Expression,在编写xpath expression的过程中需要反复的修改源代码并且反复的修改xpath expression这样才能满足所有的需要,反复的点击go。
//VariableDeclaratorId[../..//ClassOrInterfaceType[@Image =
'UnitOfWork']]/@Image) or (PrimarySuffix[ends-with(@Image, 'commit') or
'getActiveUnitOfWork')] or PrimarySuffix[ends-with(@Image, 'acquireUnitOfWork')]))
8.将写好的xpath expression转换成pmd rule。Designer可以自动生成点击菜单actions下面的create rule xml。
9.最后将生成的rule添加到ruleset中,并最好在大批量的代码中进行验证。
7. 结束语
8. 参考资料
PMD 官方文档(http://pmd.sourceforge.net/)
请参阅 Tom Copeland 撰写的文章“ Static Analysis with PMD”,这篇文章对 PMD 进行了介绍。
(http://www.onjava.com/pub/a/onjava/2003/02/12/static_analysis.html?page=1)
从 Tom Copeland 撰写的文章“ Custom PMD Rules”中学习如何编写定制 PMD 规则。
(http://www.onjava.com/pub/a/onjava/2003/04/09/pmd_rules.html)
XOM 在本文的示例中多次引用到,它是一个开源的、基于树的 API,用于处理 Java 中的 XML。 (http://www.xom.nu/)
XPath语法:(http://www.w3.org/TR/xpath)
静态分析工具PMD使用说明相关推荐
- 让开发自动化持续重构 --使用静态分析工具识别代码味道
系列内容: 此内容是该系列的一部分:让开发自动化 在过去的几年里,我曾看过很多项目的大量源代码,从精美的设计到像是用胶带绑定到一起的代码.我写过新的代码也维护过其他开发人员的源代码.我喜欢编写新的代码 ...
- 有哪些开源C ++静态分析工具? [关闭]
本文翻译自:What open source C++ static analysis tools are available? [closed] Java has some very good ope ...
- Linux平台下QtCreator集成代码静态分析工具clang-tidy和Clazy
Linux平台下QtCreator集成代码静态分析工具clang-tidy和Clazy 原文连接: https://blog.csdn.net/wsj18808050/article/details/ ...
- 序列拼接工具Bowtie使用说明
序列拼接工具Bowtie使用说明 2011-06-08 ~ ADMIN Bowtie是一个超级快速的,较为节省内存的短序列拼接至模板基因组的工具.它在拼接35碱基长度的序列时,可以达到每小时2.5亿次 ...
- benchmarksql测试mysql_数据库压力测试工具 -- BenchmarkSQL 使用说明
关于数据库的压力测试,之前写过3篇Blog: 数据库基准测试(Database Benchmarking) 说明 数据库压力测试工具 -- Hammerdb 使用说明 数据库压力测试工具 -- Swi ...
- flutter图标按钮_Flutter开发第一个项目android studio 开发工具的使用说明
Flutter开发第一个项目android studio 开发工具的使用说明 做个自我介绍 自我介绍还是有必要介绍一下的,毕竟这是网络里,你看不到我,我看不到你,只能通过文字来传递信息,本人做技术8年 ...
- PHP代码静态分析工具PHPStan
最近发现自己写的PHP代码运行结果总跟自己预想的不一样,排查时发现大多是语法错误,在运行之前错误已经种下.可能是自己粗心大意,或者说php -l检测太简单,不过的确是有一些语法错误埋藏得太深(毕竟PH ...
- 几款***常用小工具的使用说明
几款***常用小工具的使用说明 2007-07-09 07:04:55 标签:*** 工具 [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声 ...
- java自动推断类型_推断:Facebook的新Java静态分析工具
java自动推断类型 如何使用Facebook的Infer改善Java开发工作流程? 如果您与技术话题保持同步(如果您正在阅读此博客,我想您会这样做),那么您可能听说过Facebook 刚刚向公众发布 ...
最新文章
- 谁说Vim不是IDE?(四)
- ASP.NET DataSet查询结果转换为JSON格式数据
- Imageloader2-整体思路
- The Way to TiDB 3.0 and Beyond (下篇)
- [云炬ThinkPython阅读笔记]第一章 程序之道
- Ubuntu 15.04 安装 boost-python
- PS教程第二十二课:羽化选区
- 关联分析中FPGrowth算法原理及实战
- 计算机笔记本硬盘,笔记本取证之--笔记本硬盘拆卸
- 按字母排列的中国城市名称大全
- 木子案正判后的故事发展(猜想)
- 三、共阳数码管的静态显示
- [usaco6.1.1Postal Vans]
- Hadoop(二)Hive原理解析
- 拒绝校园欺凌丨盐城北大青鸟机电基地开展法制宣传讲座
- java发送带图片的邮件代码
- pycrypto 和 lua-resty-rsa 进行跨语言的RSA加密解密.md
- Android开发——进程间通信之Bundle和文件
- 笑话理解之Devil
- REST 架构指导方案
热门文章
- 公司U07 随机变量视角下的NPV估值 教材笔记
- 解释一下什么是鲁棒性
- 中国高校与研究院所计算机学科分专业点评(本贴内容仅供参考!)
- Understand教程—使用搜索功能的几种方法
- 【Try to Hack】Kerberos基础
- C# Invoke,begininvoke的用法详解
- 基于javaweb的社区居民户籍管理系统(java+ssm+jsp+js+html+mysql)
- 主存、辅存、缓存、控存、虚存的比较分析
- Integrating Factor
- handle与handler的区别