«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.