上一节使用checkstyle来规范你的项目主要解决了代码编码规范问题,比如缩进换行等。这次继续代码健康工具类PMD。

什么是PMD

PMD真的不像checkstyle这样的东西所见即所得啊,去官网找了半天也没有找到解释。官网都直接说是PMD。

We've been trying to find the meaning of the letters PMD - because frankly, we don't really know. We just think the letters sound good together.

简单来说,PMD是一个代号,是一个静态代码检测工具。它可以用来检查

  • 潜在的bug:空的try/catch/finally/switch语句
  • 未使用的代码:未使用的局部变量、参数、私有方法等
  • 可选的代码:String/StringBuffer的滥用
  • 复杂的表达式:不必须的if语句、可以使用while循环完成的for循环
  • 重复的代码:拷贝/粘贴代码意味着拷贝/粘贴bugs

总之,这是一个辅助我们检测潜在bug的工具,大大减少了人工审查成本,提高编码效率。

在gradle中使用

gradle还是一贯的简单,新建pmd.gradle

/**
* The PMD Plugin
*
* Gradle plugin that performs quality checks on your project’s Java source files using PMD
* and generates reports from these checks.
*
* Tasks:
* Run PMD against {rootDir}/src/main/java: ./gradlew pmdMain
* Run PMD against {rootDir}/src/test/java: ./gradlew pmdTest
*
* Reports:
* PMD reports can be found in {project.buildDir}/build/reports/pmd
*
* Configuration:
* PMD is very configurable. The configuration file is located at {rootDir}/config/pmd/pmd-ruleset.xml
*
* Additional Documentation:
* https://docs.gradle.org/current/userguide/pmd_plugin.html
*/ apply plugin: 'pmd' pmd {
// The version of the code quality tool to be used.
// The most recent version of PMD can be found at https://pmd.github.io
toolVersion = "5.8.1" // The source sets to be analyzed as part of the check and build tasks.
// Use 'sourceSets = []' to remove PMD from the check and build tasks.
sourceSets = [project.sourceSets.main] // The directory where reports will be generated.
reportsDir = file("$project.buildDir/reports/pmd") // Whether to allow the build to continue if there are warnings.
ignoreFailures = false // Whether or not rule violations are to be displayed on the console.
consoleOutput = true // The custom rule set files to be used.
ruleSetConfig = resources.text.fromFile("$rootProject.projectDir/config/pmd/pmd-ruleset.xml")
}

添加我们的pmd-ruleset.xml配置文件, 这个ruleset有很多种,我们可以先把所有的加上,然后在开发中调整,直到找到最合适的配置方案。因为全部的规则太多,会导致你花费大量的时间解决PMD问题。

ruleset内容可以在https://maven.apache.org/plugins/maven-pmd-plugin/examples/usingRuleSets.html 这里找到

然后在build.gradle中添加

apply from: 'pmd.gradle'

执行

./gradlew check  或者 ./gradlew build

报告位置:

build/reports/pmd/main.html

在maven中使用

maven需要把ruleset放到resources下读取,如果是单moudle项目,直接就可以。如果是多模块项目,需要额外做一些工作。

我们来新建一个项目来单独存储配置文件,build-tools. 在resources下放置ruleset。名字叫做pmd-ruleset.xml, 内容见https://maven.apache.org/plugins/maven-pmd-plugin/examples/usingRuleSets.html

然后maven install把这个子模块给安装到本地仓库。

接着修改parent pom

<build>

    <pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.10.0</version>
<dependencies>
<dependency>
<groupId>com.shuwei</groupId>
<artifactId>build-tools</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
<configuration>
<sourceEncoding>utf-8</sourceEncoding>
<minimumTokens>100</minimumTokens>
<targetJdk>${java.version}</targetJdk>
<excludes>
<exclude>**/message/*.java</exclude>
<exclude>**/generated/*.java</exclude>
</excludes>
<excludeRoots>
<excludeRoot>target/generated-sources</excludeRoot>
</excludeRoots>
<rulesets>
<ruleset>pmd-ruleset.xml</ruleset>
</rulesets>
<printFailingErrors>true</printFailingErrors>
</configuration>
<executions>
<execution>
<id>install</id>
<phase>install</phase>
<goals>
<goal>pmd</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement> <!--所有子模块都要执行的plugin-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
</plugin>
</plugins> </build> <reporting>
<!--所有子模块都要执行的报告-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
</plugin>
</plugins>
</reporting>

和上一节checkstyle不同的时候,这里的plugin下新增了dependency节点。这个节点负责加载一些资源过来,比如我们的配置文件ruleset。所以,这个dependency要先于项目存在,所以才要先单独install一下。当然,也可以把这个项目放到maven私服上,这样更简单了。

依旧把pmd的运行绑定到install命令上,这样,我们运行maven install的时候就可以进行pmd检查了。

检查报告在

j-context/target/site/pmd.html

也可以单独运行pmd

mvn pmd:pmd

idea插件

搜索安装idea pmd插件,导入我们的ruleset, 然后在项目上右键,run pmd即可。

Ruleset default内容

可以在maven官网看到: https://maven.apache.org/plugins/maven-pmd-plugin/examples/usingRuleSets.html

PMD 包含 16 个规则集,涵盖了 Java 的各种常见问题,其中一些规则要比其他规则更有争议:

基本(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)、非静态的记录器,以及在一个类中有多个记录器。

参考

添加PMD插件扫描潜在的bug的更多相关文章

  1. IDEAL葵花宝典:java代码开发规范插件 checkstyle、visualVM、PMD 插件

    前言: visualVM: 运行java程序的时候启动visualvm,方便查看jvm的情况 比如堆内存大小的分配:某个对象占用了多大的内存,jvm调优必备工具. checkstyle: CheckS ...

  2. Gradle 1.12用户指南翻译——第三十三章. PMD 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  3. Ubuntu 14.04安装Chromium浏览器并添加Flash插件Pepper Flas

    转自Ubuntu 14.04安装Chromium浏览器并添加Flash插件Pepper Flash Player Chromium谷歌的开源浏览器将不再支持Netscape浏览器插件API,Adobe ...

  4. Emacs添加主题插件(Win系统)

    Emacs添加主题插件(Win系统) */--> /* @licstart The following is the entire license notice for the JavaScri ...

  5. SSM整合中遇到的不能扫描注解的bug

    我的开发环境为: ubuntu14.04LTS 64bit; Spring Tool Suite  3.5.0.RELEASE Maven 3.2.3 SSM整合中遇到的不能扫描注解的bug 最终解决 ...

  6. IntelliJ IDEA 添加junit插件

    一.使用idea做junit测试需要添加junit插件 1.安装插件 File-->settings-->Plguins-->Browse repositories-->输入J ...

  7. eclipse手动安装alibaba代码规范插件+取消阿里编码规约插件扫描出来的警告及错误

    如果你的开发环境无法访问外网,那么手动安装阿里巴巴的代码规范插件是一个不错的选择.另外,很多教程说该插件需要jdk1.8以上,我试了一下jdk1.7也是可以运行的,更低的版本就不知道了,貌似jdk1. ...

  8. WordPress插件扫描工具plecost

    WordPress插件扫描工具plecost   WordPress是PHP语言开发的博客平台.该平台允许用户通过插件方式扩展博客功能.由于部分插件存在漏洞,给整个网站带来安全风险.Kali Linu ...

  9. atitit.MyEclipse10 中添加svn插件故障排除

    atitit.MyEclipse10 中添加svn插件故障排除 删除\configuration \org.eclipse.update 不行... 二. 在configuration下的config ...

随机推荐

  1. WEB应用从服务器主动推送Data到客户端有那些方式?

    1)  html5 websocket 2)  WebSocket 通过 Flash 3)  XHR长时间连接 4)  XHR Multipart Streaming 5)  不可见的Iframe 6 ...

  2. Codeforces Round #373 (Div. 2) C. Efim and Strange Grade 水题

    C. Efim and Strange Grade 题目连接: http://codeforces.com/contest/719/problem/C Description Efim just re ...

  3. spring cloud 学习(10) - 利用springfox集成swagger

    对绝大多数程序员而言,写接口文档是一件痛苦的事情,相对文档,他们更愿意写代码.最理想的情况就是:代码即文档!服务开发完成后,部署上去文档就自动生成,没错,这就是springfox + swagger要 ...

  4. Android的设计尺寸

    术语和概念 屏幕尺寸 指实际的物理尺寸,为屏幕对角线的测量.为了简单起见,Android把实际屏幕尺寸分为四个广义的大小:小,正常,大,特大. 像素(PX) 代表屏幕上一个物理的像素点代表屏幕上一个物 ...

  5. AT91 USB Composite Driver Implementation

    AT91 USB Composite Driver Implementation 1. Introduction The USB Composite Device is a general way t ...

  6. IAR EWARM Checksum Technical Note

    IELFTOOL Checksum - Basic actions EW targets: ARM, RH850, RX, SH, STM8 EW component: General issues ...

  7. 使用Axure RP原型设计实践01,使用概述

    首先认识Axure RP Pro 7.0软件的默认界面布局.最上面的是工具栏区域,左侧上方的是网站地图区域(sitemap),左侧中部的是部件区域(Widgets),左侧下方的是模板区域(Master ...

  8. Windows 同一时候开启核心显卡与独立显卡(不接显示器启动核芯显卡)

    採用Mp4视频压缩格式编码时,非常耗CPU.所以决定上显卡.进行显卡加速.选择了Intel核心显卡进行视频编码加速,效果非常理想.但如今的问题是:在PC上如何同一时候开启核心显卡与独立显卡.经过几番周 ...

  9. 关于面试总结7-linux篇

    前言 现在做测试的出去面试,都会被问到linux,不会几个linux指令都不好意思说自己是做测试的了,本篇收集了几个被问的频率较高的linux面试题 常用指令 1.说出10个linux常用的指令 ls ...

  10. 从零开始写一个发送h264的rtsp服务器(上)

    转自:http://blog.csdn.net/jychen105/article/details/47006345 一.什么是RTSP 通常所说的rtsp协议其实包含三个协议: rtsp协议, rt ...