Posted at

10分で AndroidStudio + FindBugs の環境構築

More than 3 years have passed since last update.


目的

静的解析ツールであるFindBugsをAndroidStudioで利用し、Javaコードの潜在的なバグの発見、パフォーマンス改善に役立てる。その際、以下の2つの場面で利用出来る環境を構築する。


  • コーディング中にチェックを行うため、AndroidStudio上で解析

  • CIツールで定常的にチェックを行うため、コマンドラインでの解析


環境


  • Android 5.0

  • AndroidStudio 1.0.2

  • gradle 2.2.1


準備

始めにFindBugsのexclude用のフィルタファイルを作成する。これは特定のクラスやメソッド、バグの種類などをレポートに含めないようにするためのフィルタである。運用しながら不必要な報告をこのファイルに追加していけばよいが、まずは下記を記述しておく。


findbugs_filter.xml

<?xml version="1.0" encoding="UTF-8"?>

<FindBugsFilter>
<Match>
<Class name="~.*.R"/>
</Match>
<Match>
<Class name="~.*.R\$.*"/>
</Match>
</FindBugsFilter>


この設定により、R.classファイル及び、Rクラスの内部クラスを解析の対象から外すことができる。

作成した設定ファイルをAndroidStudioのプロジェクト内にコピーしておく。今回は、[PROJECT_ROOT]/config/findbugs/findbugs_filter.xmlとして追加した。


AndroidStudio上で実行するための環境設定

FindBugs-IDEAプラグインを利用する


  • Android Studio > Preferences > Plugins で FindBugs-IDEA を検索し、インストールする


    • 執筆時のFindBugs-IDEAのバージョンは0.9.994



  • Android Studio > Preferences > FindBugs-IDEA


    • Reporting > Minimum confidence to report を Low に設定


      • Low に設定することで低レベルの問題まで報告されるようになる



    • Filters > Exclude filter files にfindbugs_filter.xmlを追加

    • Advanced にチェック

    • Analysis effort を Maximal に設定


      • この設定は Advanced がチェックされていると見えるようになる





analysis_effort.png


AndroidStudio上での実行

実行する前に一度、Build > Make Project でビルドを行う。これはFindBugsがソースコードではなく、Javaバイトコードを解析するため。

FindBugs-IDEAをインストールした時点で、AndroidStudio上の様々な場所からFindBugsの実行を行うことができるが、お勧めはFindBugs-IDEAタブのAnalyze Scope Filesボタンからの実行。画像のようにスコープ内の指摘項目と内容が表示される。

findbugs_tab.png

余談になるが、スコープもカスタマイズしておくとCheckstyleやインスペクションでも流用出来る。とりあえずsrcフォルダ以下のスコープは作っておくと便利。


  • Android Studio > Preferences > Scopes

  • Scopes に新しいスコープを追加する

  • 以下のパターンを追加する


    • file[project名]:src//*



  • 複数プロジェクトが有る場合は || でつなげて追記する

  • Share scope にチェック


コマンドラインで実行するための環境設定


  • [MODULE_ROOT]/build.gradle にfindbugsプラグインを適用する


[MODULE_ROOT]/build.gradle

apply plugin: 'findbugs'



  • findbugsタスクを追加する


[MODULE_ROOT]/build.gradle

task findbugs(type: FindBugs) {

ignoreFailures = true
effort = "max"
reportLevel = "low" // *どのレベルの報告まで対応するかで変更*
excludeFilter = new File("${project.rootDir}/config/findbugs/findbugs_filter.xml")
classes = files("build/intermediates/classes/")
source 'src/main'
include '**/*.java'
reports {
xml {
destination "${project.rootDir}/build/reports/findbugs_report.xml"
}
}
classpath = files()
}


  • ライブラリモジュールも解析対象にしたい場合は、それぞれのモジュールのbuild.gradleを編集しても良いが、下記のようにsourceを追加していけばよい


[MODULE_ROOT]/build.gradle

task findbugs(type: FindBugs) {

ignoreFailures = true
effort = "max"
reportLevel = "low"
excludeFilter = new File("${project.rootDir}/config/findbugs/findbugs_filter.xml")
classes = files("build/intermediates/classes/")
classes += files("${project.rootDir}/[モジュール名]/build/intermediates/classes/") // *ここに追加*
source 'src/main'
source "${project.rootDir}/[モジュール名]/src/main" // *ここに追加*
include '**/*.java'
reports {
xml {
destination "${project.rootDir}/build/reports/findbugs_report.xml"
}
}
classpath = files()
}


  • checkタスクにfindbugsタスクを追加する


[MODULE_ROOT]/build.gradle

check.dependsOn 'findbugs'



コマンドラインで実行


  • ターミナルより$./gradlew findbugsを行うと結果が${project.rootDir}/build/reports/findbugs_report.xmlへ保存される

  • checkタスクにfindbugsタスクを追加した場合は$./gradlew checkでも同様にFindBugsの結果が保存される


おまけ

findbugs_report.xmlはJenkinsなどのCIツールを利用することで確認するのがお勧め。ただし、CIツールを利用しない場合は、htmlで出力することもできる。report部分を下記のように修正する。


[MODULE_ROOT]/build.gradle

    reports {

xml.enabled = false
html.enabled = true
html {
destination "${project.rootDir}/build/reports/findbugs_report.html"
}
}

このとき一つ問題があり、FindBugsはShift_JISでレポートを作成し、htmlファイルがUTF-8だと文字化けが起きる。解決方法の1つとして、出力されたhtmlファイルをFile#getTextメソッドなどでUTF-8として読み込み、File#writeメソッドでShift-JISとして書き込むことで変換する、というタスクを追加し、先ほど作成したfindbugsタスクに依存を持たせる。