1概要

簡単に言うと、https://pmd.github.io/[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>

ここで設定にルールセットを追加していることに注意してください。これらは、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サイト
……

生成されたレポートは

pmd.html

という名前で、

target/site

フォルダーにあります。

……
ファイル

com/baeldung/pmd/Cnt.java

違反ライン

Cnt 1〜10のような短いクラス名は避けてください
短いメソッド名を使用しない3
b 3のような短い名前の変数を避ける
3のような短い名前の変数を避ける
中括弧5なしでif …​ else文を使用しないでください。
中括弧なしでif …​ else文を使用しないでください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.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

ファイルを作成します。もちろん、既存のルールセットファイルの1つを例として使用し、それを新しいファイルにコピーアンドペーストし、そこから古いルールをすべて削除し、名前と説明を変更することができます。

<?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>

  • 次へ – 除外パターンを使用してルールセットからファイルを除外することもできます。

一致する除外パターンがあるが、一致する包含パターンがない場合、ファイルは処理から除外されます。

ソースファイルパス内のパス区切り文字は「/」文字になるように正規化されているため、複数のプラットフォームで同じルールセットを透過的に使用できます。

さらに、このexclude/includeテクニックは、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. 結論

このクイック記事では、Javaコードの静的分析に焦点を絞った柔軟で高度に設定可能なツールであるPMDを紹介しました。

いつものように、このチュートリアルで提供されている完全なコードはhttps://github.com/eugenp/tutorials/tree/master/static-analysis[over on Github]から入手できます。