PMD (Java Source Code Analyzer)

Table of Contents

1. PMD 简介

PMD 是一个代码静态分析工具(主要针对 Java 语言,它也支持其它语言),可以发现代码中的一些问题,比如:

  • Possible bugs - empty try/catch/finally/switch statements
  • Dead code - unused local variables, parameters and private methods
  • Suboptimal code - wasteful String/StringBuffer usage
  • Overcomplicated expressions - unnecessary if statements, for loops that could be while loops
  • Duplicate code - copied/pasted code means copied/pasted bugs

PMD 使用 JavaCC 对 java, plsql, jsp, velocity 等程序进行语法分析。

PMD 可以和 Eclipse,IntelliJ 等等工具进行集成,参考:https://pmd.github.io/pmd-5.5.0/usage/integrations.html

注:PMD 这三个字母没有什么含义,其作者说仅仅是由于它们读起来朗朗上口,你可以认为它是“Pretty Much Done”或者“Project Mess Detector”等的缩写。参考:https://pmd.github.io/pmd-5.5.0/overview/meaning.html

2. 在 maven 工程中使用 PMD

第一步,在工程的 pom.xml 文件中,加入下面内容:

<project>
  ...
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-pmd-plugin</artifactId>
        <version>3.8</version>
      </plugin>
    </plugins>
  </reporting>
  ...
</project>

第二步,执行下面命令:

$ mvn pmd:pmd

第三步,查看报告。
上面命令执行结束后,会在 target 目录中生成报告文件。

$ find target/
target/
target/java-empty.xml
target/site
target/site/pmd.html
target/pmd.xml
target/java-basic.xml
target/java-unnecessary.xml
target/java-unusedcode.xml
target/java-imports.xml

直接用浏览器打开文件“target/site/pmd.html”即可。

参考:
http://maven.apache.org/plugins/maven-pmd-plugin/usage.html
https://pmd.github.io/pmd-5.7.0/usage/mvn-plugin.html

2.1. 和 JXR 集成

在 PMD 生成的报告中,会显示发现问题的行号,但不能点击。使用工具 JXR 可以建立交互引用,这样点击行号就可以直接查看到那行的源代码了。
在工程 pom.xml 文件中加入下面内容即可:

<project>
  ...
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-pmd-plugin</artifactId>
        <version>3.8</version>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jxr-plugin</artifactId>
        <version>2.5</version>
      </plugin>
    </plugins>
  </reporting>
  ...
</project>

执行下面命令生成可交叉引用的 html 文件及 pmd 报告:

$ mvn jxr:jxr    # 首先,使用jxr生成交叉引用的html文件
$ mvn pmd:pmd    # 然后,生成pmd报告

上面命令可合并为 mvn jxr:jxr pmd:pmd

3. PMD 报告实例

假设 maven 工程中有下面 Java 代码:

 1: package com.mycompany.app;
 2: 
 3: import java.io.BufferedReader;
 4: import java.io.IOException;
 5: import java.nio.file.Files;
 6: 
 7: public class App {
 8:     public static enum WeekDay {
 9:         SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
10:     };
11: 
12:     public static void main( String[] args ) {
13:         System.out.println( "Hello World!" );
14: 
15:         try (BufferedReader reader = Files.newBufferedReader(Files.createTempFile(null, ".txt"))) {
16:             String line = null;
17:             while ((line = reader.readLine()) != null) {
18:                 System.out.println(line);
19:             }
20:         } catch (IOException x) {
21:         }
22:     }
23: }

执行命令 mvn jxr:jxr pmd:pmd 后,生成的报告(即文件 target/site/pmd.html)如图 1 所示。

pmd_report_example.jpg

Figure 1: PMD 报告实例

这个例子中,PMD 发现了两个问题。一是枚举的 static 修饰符是冗余的(枚举默认都是 static 的,可以去掉 static修饰符),二是发现了空的 catch 语句(你应该记录一些日志等)。

Author: cig01

Created: <2017-02-05 Sun>

Last updated: <2018-02-14 Wed>

Creator: Emacs 27.1 (Org mode 9.4)