1. 概述
简而言之,PMD是一个源代码分析器,用于查找常见的编程缺陷,如未使用的变量、空的捕获块、不必要的对象创建等等。
它支持Java、JavaScript、Salesforce.com Apex、PLSQL、Apache Velocity、XML、XSL。
在本文中,我们将重点介绍如何使用PMD在Java项目中执行静态分析。
2. 先决条件
让我们首先将PMD设置到Maven项目中-使用和配置maven-pmd-plugin:
<project>
...
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.23.0</version>
<configuration>
<rulesets>
<ruleset>/rulesets/java/braces.xml</ruleset>
<ruleset>/rulesets/java/naming.xml</ruleset>
</rulesets>
</configuration>
</plugin>
</plugins>
</reporting>
</project>
你可以在此处找到最新版本的maven-pmd-plugin。
请注意我们如何在此处的配置中添加规则集-这些是从PMD核心库中已经定义规则的相对路径。
最后,在运行所有内容之前,让我们创建一个包含一些明显问题的简单Java类-PMD可以开始报告问题:
public class Ct {
public int d(int a, int b) {
if (b == 0)
return Integer.MAX_VALUE;
else
return a / b;
}
}
3. 运行PMD
使用简单的PMD配置和示例代码,让我们在构建目标文件夹中生成一份报告:
mvn site
生成的报告名为pmd.html,位于target/site文件夹中:
Files
cn/tuyucheng/taketoday/pmd/Cnt.java
Violation Line
Avoid short class names like Cnt 1–10
Avoid using short method names 3
Avoid variables with short names like b 3
Avoid variables with short names like a 3
Avoid using if...else statements without curly braces 5
Avoid using if...else statements without curly braces 7
如你所见,我们没有得到结果,根据PMD的数据,报告显示了Java代码中的违规情况和行号。
4. 规则集
PMD插件使用5个默认规则集:
- basic.xml
- empty.xml
- imports.xml
- unnecessary.xml
- unusedcode.xml
你可以使用其他规则集或创建自己的规则集,并在插件中配置这些规则集:
<project>
...
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.23.0</version>
<configuration>
<rulesets>
<ruleset>/rulesets/java/braces.xml</ruleset>
<ruleset>/rulesets/java/naming.xml</ruleset>
<ruleset>/usr/pmd/rulesets/strings.xml</ruleset>
<ruleset>http://localhost/design.xml</ruleset>
</rulesets>
</configuration>
</plugin>
</plugins>
</reporting>
</project>
请注意,我们使用相对地址、绝对地址甚至URL作为配置中“ruleset”值的值。
自定义项目规则的一个简洁策略是编写自定义规则集文件,在此文件中,我们可以定义要使用的规则、添加自定义规则以及自定义在官方规则集中包含/排除哪些规则。
5. 自定义规则集
现在让我们从PMD中现有的规则集中选择我们想要使用的特定规则- 并且让我们自定义它们。
首先,我们将创建一个新的ruleset.xml文件。当然,我们可以以现有的规则集文件为例,将其复制粘贴到新文件中,删除所有旧规则,并更改其名称和描述:
<?xml version="1.0"?>
<ruleset name="Custom ruleset"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0
http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
This ruleset checks my code for bad stuff
</description>
</ruleset>
其次,我们来添加一些规则引用:
<!-- We'll use the entire 'strings' ruleset -->
<rule ref="rulesets/java/strings.xml"/>
或者添加一些具体规则:
<rule ref="rulesets/java/unusedcode.xml/UnusedLocalVariable"/>
<rule ref="rulesets/java/unusedcode.xml/UnusedPrivateField"/>
<rule ref="rulesets/java/imports.xml/DuplicateImports"/>
<rule ref="rulesets/java/basic.xml/UnnecessaryConversionTemporary"/>
我们可以自定义规则的消息和优先级:
<rule ref="rulesets/java/basic.xml/EmptyCatchBlock" message="Must handle exceptions">
<priority>2</priority>
</rule>
你还可以像这样自定义规则的属性值:
<rule ref="rulesets/java/codesize.xml/CyclomaticComplexity">
<properties>
<property name="reportLevel" value="5"/>
</properties>
</rule>
请注意,你可以自定义单个引用规则。除了规则的类别之外,自定义规则集中的所有内容都可以被覆盖。
接下来,你还可以从规则集中排除规则:
<rule ref="rulesets/java/braces.xml">
<exclude name="WhileLoopsMustUseBraces"/>
<exclude name="IfElseStmtsMustUseBraces"/>
</rule>
接下来,你还可以使用排除模式从规则集中排除文件,并使用可选的覆盖包含模式。
当存在匹配的排除模式,但没有匹配的包含模式时,文件将被排除在处理之外。
源文件路径中的路径分隔符被规范化为“/”字符,因此相同的规则集可以在多个平台上透明地使用。
此外,无论如何使用PMD(例如命令行、IDE、Ant),此排除/包含技术都有效,从而更容易在整个环境中保持PMD规则的应用一致。
这是一个简单的例子:
<?xml version="1.0"?>
<ruleset ...>
<description>My ruleset</description>
<exclude-pattern>.*/some/package/.*</exclude-pattern>
<exclude-pattern>
.*/some/other/package/FunkyClassNamePrefix.*
</exclude-pattern>
<include-pattern>.*/some/package/ButNotThisClass.*</include-pattern>
<rule>...
</ruleset>
6. 总结
在这篇简短的文章中,我们介绍了PMD-一种灵活且高度可配置的工具,专注于Java代码的静态分析。
Post Directory
