PMD 標準的な ruleset とは何かを調べてみる | Monotalk続き、
Githubリポジトリから、PMD ルールセットを取得した実装を流用し、
Findbugs Filterファイルを取得して集計してみました。
集計結果を元に、標準的な findbugs-excludes.xml作成してみます。


集計してからわかったこと

Findbugs exclude 設定のみだと思い込んでいましたが、
include 設定もありました。 幸い集計対象に含めていなかったので、
除外設定としての誤りはないかと思いますので、そのまま結果を記載します。

計測の対象から、include ファイルが漏れているので、そちらのいつか集計したい。。


目次


サンプルの抽出

  • 対象プロジェクトはこちら同様です。

  • 上記のリポジトリからファイル名が、以下の名前と一致するものを抽出します。

    • findbugs-rules.xml
    • findbugs-exclude-filter.xml
    • findbugs.xml
    • findbugs-exclude.xml
    • findbugs-filter.xml
    • exclude.xml

集計方法

  • 除外されたルール数をカウントします。
    Findbugs PMD違う点は、PMD適用するルールを定義するのに対して、
    Findbugs除外するルールを定義する作りになっています。
    このため、どれだけ除外されているかをカウントします。

  • ルールは、patternと、category codeより定義が可能です。
    pattern最小単位であるため、category codeルールが記述されている場合は、
    関連 pattern取得して、集計します。
    codecategory pattern関係は、findbugs/findbugs.xml at master · findbugsproject/findbugs から、
    取得しました。


集計に使用するGithub API

  • 集計に使用する Github APIこちら同様です。

集計結果

1. Findbugsのルールファイルを保持しているプロジェクト数

  • 146/5419 プロジェクト Findbugs定義ファイルだけなら、265個 ありました。
    1リポジトリに何個もファイルがあったりするので、その重複を排除すると、
    146リポジトリで使用されていました。
    少なくとも、PMDよりは多くのプロジェクトで使用されているようです。

2. 全体で、除外されているルールの TOP10

NOルール名カウント
1EI_EXPOSE_REP223
2EI_EXPOSE_REP22
3SE_COMPARATOR_SHOULD_BE_SERIALIZABLE13
4SE_BAD_FIELD11
5DM_DEFAULT_ENCODING9
5MS_PKGPROTECT9
7MS_MUTABLE_ARRAY8
7DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED8
8SE_BAD_FIELD_INNER_CLASS7
8RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE7
9ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD6
9DM_EXIT6
9SE_NO_SERIALVERSIONID6
9PT_RELATIVE_PATH_TRAVERSAL6
9JLM_JSR166_UTILCONCURRENT_MONITORENTER6
9RV_RETURN_VALUE_IGNORED_BAD_PRACTICE6
  • 全体なので、指定なし[JAVAプロジェクト全体で除外している] ルールのTOP10になります。

  • 感覚ベースでの話になりますが、Findbugsについては、行き当たりばったり(バグが検出されたのに応じて。)
    除外適用されるルールが多いように思われます。
    ※超ぱっと見の感覚での話です。

  • 全体的に除外しているものは少なく、
    クラス指定、メソッド指定などした上で除外することが多いように思われます。

3. クラススコープで除外されているルールの TOP10

続けます。 Class スコープ(正規表現含む)場合の、除外対象 TOP10 になります。

NOルール名カウント
1ALL219
2EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS195
3EQ_UNUSUAL114
4CN_IDIOM_NO_SUPER_CALL83
5EI_EXPOSE_REP280
6SE_NO_SUITABLE_CONSTRUCTOR77
7EI_EXPOSE_REP68
8BC_UNCONFIRMED_CAST62
9DM_DEFAULT_ENCODING60
10NM_SAME_SIMPLE_NAME_AS_INTERFACE59
10NM_SAME_SIMPLE_NAME_AS_SUPERCLASS59
  • 全体で除外されているものと、傾向は違います。
    確かにクラスベースで発生するが、見逃したいバグが除外されているように思います。

  • EI_EXPOSE_REP2 EI_EXPOSE_REP全体でも、クラスベースでも除外されています。
    問題となる場合は、ものすごいわかりにくいバグになると思うのですが、基本除外したい人が多い。いうことでしょうか?

  • NM_SAME_SIMPLE_NAME_AS_INTERFACE 等は Class ならではの除外ルールかもしれません。

4. メソッドスコープで除外されているルールの TOP10

続けます。 Method スコープ(正規表現含む)場合の、除外対象 TOP10 になります。

NOルール名カウント
1DM_EXIT40
2NP_BOOLEAN_RETURN_NULL23
2EI_EXPOSE_REP23
4SF_SWITCH_FALLTHROUGH20
5BC_UNCONFIRMED_CAST16
6OBL_UNSATISFIED_OBLIGATION15
6NP_LOAD_OF_KNOWN_NULL_VALUE15
8EI_EXPOSE_REP214
9REC_CATCH_EXCEPTION13
9NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE13
10JLM_JSR166_UTILCONCURRENT_MONITORENTER12
  • 確かにメソッドのスコープで除外設定したくなるルールに思われます。

  • NP_BOOLEAN_RETURN_NULLしたくなるケースってどのような時だろう? と思いました。
    True (存在する) or False (存在しない) or Null (Unknown) みたいなケースでしょうか?
    RDB のような Null表現するのに使うんですかね?

  • EI_EXPOSE_REP EI_EXPOSE_REP2ジャンル問わず、よくExclude されていますwww。

5. フィールドスコープで除外されているルールの TOP10

更に続けます。 Field スコープ場合の、除外対象 TOP10 になります。

NOルール名カウント
1IS2_INCONSISTENT_SYNC126
2SE_TRANSIENT_FIELD_NOT_RESTORED23
2URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD23
4SE_BAD_FIELD18
5MS_SHOULD_BE_FINAL12
6ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD9
7EI_EXPOSE_REP27
8EI_EXPOSE_REP6
8UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD6
8MS_PKGPROTECT6

シリアライズ、や、同期化に関する警告の抑制が多いようです。

  • IS2_INCONSISTENT_SYNC同期化されていない Field場合、出力される警告なので、
    問題がある場合と、ない場合があるのだと思います。

  • EI_EXPOSE_REP2 EI_EXPOSE_REPここでも抑制の対象になっています。


Findbugsルールファイル

以下、ルールで作成しました。

  • 各カテゴリの TOP10抽出し、重複をマージ

    <FindBugsFilter>
        <Match>
            <Or>
                <Bug pattern="BC_UNCONFIRMED_CAST" />
                <Bug pattern="CN_IDIOM_NO_SUPER_CALL" />
                <Bug pattern="DM_DEFAULT_ENCODING" />
                <Bug pattern="DM_EXIT" />
                <Bug pattern="DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED" />
                <Bug pattern="EI_EXPOSE_REP" />
                <Bug pattern="EI_EXPOSE_REP2" />
                <Bug pattern="EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS" />
                <Bug pattern="EQ_UNUSUAL" />
                <Bug pattern="IS2_INCONSISTENT_SYNC" />
                <Bug pattern="JLM_JSR166_UTILCONCURRENT_MONITORENTER" />
                <Bug pattern="MS_MUTABLE_ARRAY" />
                <Bug pattern="MS_PKGPROTECT" />
                <Bug pattern="MS_SHOULD_BE_FINAL" />
                <Bug pattern="NM_SAME_SIMPLE_NAME_AS_INTERFACE" />
                <Bug pattern="NM_SAME_SIMPLE_NAME_AS_SUPERCLASS" />
                <Bug pattern="NP_BOOLEAN_RETURN_NULL" />
                <Bug pattern="NP_LOAD_OF_KNOWN_NULL_VALUE" />
                <Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE" />
                <Bug pattern="OBL_UNSATISFIED_OBLIGATION" />
                <Bug pattern="REC_CATCH_EXCEPTION" />
                <Bug pattern="SE_BAD_FIELD" />
                <Bug pattern="SE_BAD_FIELD_INNER_CLASS" />
                <Bug pattern="SE_COMPARATOR_SHOULD_BE_SERIALIZABLE" />
                <Bug pattern="SE_NO_SUITABLE_CONSTRUCTOR" />
                <Bug pattern="SE_TRANSIENT_FIELD_NOT_RESTORED" />
                <Bug pattern="SF_SWITCH_FALLTHROUGH" />
                <Bug pattern="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD" />
                <Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" />
                <Bug pattern="UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD" />
            </Or>
        </Match>
    </FindBugsFilter>

  • Findbugs感覚的な使われ方を考えると、乱暴な気はします。
    最初かけていなかったけど、途中導入してやたら大量の警告にみまわれる場合で、
    ある程度、対象のバグを絞り込みたい場合は、上記のルールを適用しておけばいいのではと考えます。
    が、実プロジェクトでうまくいくかどうかは試していないので、わからないです!

  • 集計詳細はこちらのスプレッドシート記載しました。

PMD集計しやすかった。
のに比べて、Findbugs集計しにくかったのは、定義ファイルの具合にあるのだと思います。
解析のしやすい構造を人書いて設定してもらうのは、
実は設定しにくい? のかもしれません。
以上です。

コメント