ふるてつのぶろぐ

福岡在住のエンジニアです。

写真提供:福岡市

いまだにJava 8 備忘録 - SpotBugsの使い方

今日すること

こんにちはふるてつです。
きょうはSpotBugsのおはなしをします。
f:id:tetsufuru:20210531211456p:plain:w300
SpotBugsJavaの静的解析ツールでCheckstyleとおなじくよく見かけるツールです。
SpotBugsプラグインには開発画面上で動かすSpotBugs Eclipse pluginGradleなどのタスクで動かすSpotBugs Gradle pluginの2種類があります。
まずは開発画面上で動かすSpotBugs Eclipse pluginを説明します。

1. SpotBugs Eclipse plugin の設定

1 - 1. SpotBugs Eclipse plugin のインストール

インストールはEclipse marketplaceを使います。
Eclipse のメニューから「ヘルプ」-「Eclipseマーケットプレイス」を選びます。
そして「Eclipseマーケットプレイス」の画面で「SpotBugs Eclipse plugin」などのキーワードで検索してインストールします。
f:id:tetsufuru:20210601001050p:plain

※ここで注意点ですが、Pleiades のオールインワンなどはすでにビルトインでSpotBugs Eclipse pluginが入っていると思います。
お使いの環境にSpotBugs Eclipse pluginが入っているかは設定画面から確認できます。
Eclipse のメニューから「ウィンドウ」-「設定」を選び、設定画面の左側メニュー欄で「Java」をクリックします。
Java」のサブメニューの中に「SpotBugs」が表示されていればインストール済です。
f:id:tetsufuru:20210601003800p:plain
インストールされているSpotBugsのバージョンを確認しておきます。
「SpotBugs」の設定画面の3番目のタブ(プラグインおよびその他の設定)画面で確認できます。
わたしの環境では4.2.0になっています、あとで Gradle 側の設定を書くときに参考にするのでおぼえておきます。
f:id:tetsufuru:20210601003925p:plain

1 - 2. 「分析力」などの設定

次にSpotBugs Eclipse pluginの設定を行います
設定できる項目はざっとみて4項目あります。

  • 「分析力」
  • 「報告する最小ランク」
  • 「レポートする最低の信頼度」
  • 「報告(可視)バグ・カテゴリー」

a「分析力」

分析力ですがSpotBugsのドキュメントを確認します
下記になります、こちらの「分析力」によってチェックする内容が変わります。
f:id:tetsufuru:20210610224257p:plain 参考:分析力 — spotbugs 4.2.3 ドキュメント

表の右端の列 max が一番多くの項目をチェックするのでそちらを選択したいと思います
(ちなみにデフォルトの「分析力」は右端から2番目の more の列になります)
Eclipse では「最大」、「最小」、「デフォルト」を選択できますが、 maxに相当する「最大」を選んでおきます。

b「報告する最小ランク」

「報告する最小ランク」は高くするほど軽微なものまで報告されます
ずべて確認したいのでスライダーで 20 にまで上げておきます。

c「レポートする最低の信頼度」

わかりずらい項目ですが、まずここでいう「信頼度」はバグの可能性と思うといいです
「信頼度」が高いとバグである可能性が高くて、低いとバグではないかもしれないという感じです
そして「レポートする最低の信頼度」ですが high を設定するとバグの確立が高いものしかレポートされません
バグでなさそうなものまでレポートしてほしい場合は、low を設定します、わたしは low にします。

d「報告(可視)バグ・カテゴリー」

報告するカテゴリーが選択できます、とりあえず全部チェックONにしました。

f:id:tetsufuru:20210601153929p:plain
まとめるとわたしの設定は上記のようになります

1 - 3. 除外設定

わたしはとくに除外設定は行っていませんが「SpotBugs」の設定画面の2番目のタブ(フィルター・ファイル)で設定できると思います
除外用のxmlファイルを選択できるようです f:id:tetsufuru:20210601155019p:plain

xmlファイルの記入例はこちらにあります、ご参考までに。
f:id:tetsufuru:20210601155335p:plain
参考:フィルタファイル — spotbugs 4.2.3 ドキュメント

2. SpotBugs Gradle plugin の設定

2 - 1. SpotBugs Gradle plugin のインストール

ではGradleのタスクで動かす方のSpotBugsについて説明します
これまでにセクション1で説明したのは Eclipse でリアルタイムに動かすプラグインで、これから説明するのはそれとは別物と思ってください。
こちらはリアルタイムではなくGradlebuildコマンドを実行したときにタスク実行されてソースをチェックします。
ビルドをせずチェックのみをおこないたい場合はcheckコマンドで単独で実行できます。

Gradleの設定は Gradle のサイトを参考にします、下記です。
f:id:tetsufuru:20210603001644p:plain 参考:Gradle - Plugin: com.github.spotbugs

最新の書き方とレガシーな書き方が書いてあります、わたしの場合はGradleのマルチプロジェクトにしていて、 親プロジェクトの中で両方の書き方を使っています。

わたしの build.gradle の内容
関係ない項目をだいぶ省略してますがわたしはこのような感じで書いています。

buildscript {
    ext {
        spotbugsVersion = '4.7.1'
        spotbugsToolVersion = '4.2.0'
    }
}

plugins {
    id "com.github.spotbugs" version "${spotbugsVersion}" // ←これは SpotBugs Gradle plugin のバージョン
}

subprojects {
    apply plugin: 'com.github.spotbugs'

    spotbugs {
        toolVersion = "${spotbugsToolVersion}" // ←これはSpotBugs自体のバージョン
        includeFilter = rootProject.file('config/spotbugs/spotbugs-include-filter.xml')
        spotbugsMain {
            reports {
                html {
                    enabled = true
                    stylesheet = 'fancy-hist.xsl'
                }
            }
        }
    }
}
project(':prj-sub') {}

project(':prj-main') {
    dependencies {
        implementation project(':prj-sub')
    }
}
  • plugins{} について
    まずは plugins の中で SpotBugs を使うよう宣言しておきます
    このバージョンは Gradle plugin のバージョンを設定します。
  • subprojects{} について
    そして子プロジェクトの中の設定は subprojects{} の中で行います
    apply plugin と書いて、その下の spotbugs{} の中で細かい設定をおこないます
  • spotbugs{} について
    toolVersion はSpotBugs自体のバージョンを選択します
    わたしは画面側の Eclipse plugin と同じバージョンにしたいので最初のセクションでしらべておいた 4.2.0 にします
    画面側でバグ・カテゴリーをすべてチェックONにしていたので Gradle 側でも同じ設定にします。 その設定は xml ファイルに書いて includeFilter で指定します
    (includeFilter の内容は別途下で説明します)
    最後の spotbugsMain{} はレポートの設定です、 このあたりの書き方は SpotBugs の git の readme が参考になるとおもいます、下記のような内容が書いてあります。
    f:id:tetsufuru:20210603011408p:plain f:id:tetsufuru:20210602235544p:plain 参考:GitHub - spotbugs/spotbugs-gradle-plugin

2 - 2. includeファイルについて

わたしの環境では include ファイルにバグ・カテゴリーの設定を書いています
画面側で設定したバグ・カテゴリーと同じものを Gradle 側でも設定したいので使っています。
spotbugs-include-filter.xml の内容例

<?xml version="1.0"?>
<FindBugsFilter>
    <Match><Bug category="BAD_PRACTICE,MALICIOUS_CODE,CORRECTNESS,PERFORMANCE,SECURITY,STYLE,EXPERIMENTAL,MT_CORRECTNESS,I18N" /></Match>
</FindBugsFilter>

FindBugsFilterタグの中にMatchタグとBugタグを追加して、category= で報告させたいバグ・カテゴリーをカンマ区切りで設定します
すべてのクラスファイルをチェックしたいので、Matchタグの中にはなにも条件を書いていません
BAD_PRACTICEは「悪い記述」のことで MALICIOUS_CODE は「悪意があるコードの脆弱性」のことです
これらのキーワードがどのカテゴリに該当するかはSpotBugsのドキュメントに書いてありました。 下のページの赤い部分です
f:id:tetsufuru:20210603004559p:plain 参考:Bug descriptions — spotbugs 4.2.3 documentation

あとこのファイルの置き場所は下記フォルダ内にしています。

[プロジェクト直下]/config/spotbugs/

2 - 3. Gradle で check コマンドを実行

これで一通りの設定が終わりました。
では check コマンドを実行してみます、プロジェクト直下で gradle のラッパーのコマンドを実行します。

gradlew check

実行結果はプロジェクト直下/build/reports/spotbugs/ に html ファイルが出力されます。
main.html を開いてみます、下のようなイメージになります。

レポートの例
f:id:tetsufuru:20210603005541p:plain

感想


おつかれさまでした。
今回はSpotBugsついて書きました。
SpotBugsはクラスの作りなど根本から変えないと対応できないような指摘をよくしてくるので あとから導入すると結構な目にあいます。
できるだけ早いタイミングで導入したほうが楽だとおもい書きました
少しでも皆さんの参考になればと思います。

それではまた😎