«1. Обзор
Проще говоря, PMD — это анализатор исходного кода, который находит распространенные ошибки программирования, такие как неиспользуемые переменные, пустые блоки catch, создание ненужных объектов и т. д.
Он поддерживает Java, JavaScript, Salesforce.com Apex, PLSQL, Apache Velocity, XML, XSL.
В этой статье мы сосредоточимся на том, как использовать PMD для выполнения статического анализа в проекте Java.
2. Предварительные условия
Начнем с настройки PMD в проекте Maven – использование и настройка плагина maven-pmd:
<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 здесь.
Обратите внимание, что здесь мы добавляем наборы правил в конфигурацию — это относительный путь к уже определенным правилам из основной библиотеки 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/baeldung/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 использует пять наборов правил по умолчанию: настройте их в плагине:
-
Обратите внимание, что мы используем либо относительный адрес, либо абсолютный адрес, либо даже URL — в качестве значения параметра «набор правил» в конфигурации.
Чистая стратегия для настройки правил, которые будут использоваться для проекта, состоит в том, чтобы написать собственный файл набора правил. В этом файле мы можем определить, какие правила использовать, добавить пользовательские правила и настроить, какие правила включать или исключать из официальных наборов правил.
<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>
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"/>
И вы также можете настроить значение свойства правила, например this:
<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 во всей вашей среде.
Вот краткий пример:
6. Заключение
В этой быстрой статье мы представили PMD — гибкий и легко настраиваемый инструмент, ориентированный на статический анализ кода Java
<?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>
Как всегда, полный код, представленный в этом руководстве, доступен на Github.
«
As always, the full code presented in this tutorial is available over on Github.