1. Обзор
Проще говоря, PMD — это анализатор исходного кода для поиска распространенных ошибок программирования, таких как неиспользуемые переменные, пустые блоки catch, создание ненужных объектов и т. д.
Он поддерживает 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.7</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
com/foreach/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 использует пять наборов правил по умолчанию:
базовый.xml
пустой.xml
импорт.xml
ненужный.xml
неиспользованный код.xml
Вы можете использовать другие наборы правил или создавать свои собственные наборы правил и настраивать их в плагине:
<project>
...
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.7</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 — в качестве значения параметра «набор правил» в конфигурации.
Чистой стратегией настройки правил, которые следует использовать в проекте, является написание пользовательского файла набора правил . В этом файле мы можем определить, какие правила использовать, добавить пользовательские правила и настроить, какие правила включать или исключать из официальных наборов правил.
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.
Как всегда, полный код, представленный в этом руководстве, доступен на Github .