Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

FindBugsのバグパターンを実装する

SLF4J用PMDルールセットの実装に限界が見えたのでFindBugsに乗り換えました。で、FingBugsプラグイン実装関連の日本語情報がわりとないようなので、試行錯誤の過程を残しておきます。まだ自分も完全にはできていないので、情報をお持ちでしたらぜひご指摘ください。

やるべきこと

  • プロジェクトを用意する(2パターン)
    • FindBugs自身をForkする(テスト実装支援アノテーションを利用しやすそう。LGPL
    • プラグインとして実装する(今回はコレを選択)
  • テストを書く
  • Detectorを実装する
  • XMLとclassファイルをjarに固める

参考情報

整理された情報はほぼ無いのでコードを読むのが手っ取り早い。非公式だがfb-contribのコードも参考になる。

テストケース実装

コードとwikiを読む限りでは以下の様な機構が用意されているようだがまだ使っていない。そもそもプラグイン開発に流用できるのか不明。

  • バグを表す最小限のクラスをテストケースとして用いる
  • 期待するバグを@ExpectWarningアノテーションで明示
  • バグとして判断すべきでないケースもテストケースとして追加する場合は@NoWarningアノテーションを用いる

Detectorの実装

パッケージの作成

findbugs.xmlとmessages.xml、bugrank.txtをjarに含める必要がある様子。ただし公式サイトにあるfindbugs.xmlの書き方は間違っているので公式wikiを参照すること。

Mavenで開発する場合、findbugs.xmlをsrc/main/resourcesに置くとテストが回らない。findbugs自身がこのfindbugs.xmlを読み込んでしまい、以下の様なエラーが出る。

Core pluginfindbugs-2.0.1.jar doesn't contain findbugs.xml; got file:/workspace/github/findbugs-slf4j/bug-pattern/target/classes/findbugs.xml

回避策として、テスト実行時はXMLをクラスパスに含めない。残念な対応だが仕方なし。今回はsrc/main/metaディレクトリにXMLなどを配置し、以下のプロファイルをpom.xmlに置いた。リリース時にテストしないのはかなりひどいのでもうちょっと考えた方がいい。

  <profiles>
    <profile>
      <id>release</id>
      <activation>
        <property>
          <name>performRelease</name>
          <value>true</value>
        </property>
      </activation>
      <properties>
        <maven.test.skip>true</maven.test.skip>
      </properties>
      <build>
        <resources>
          <resource>
            <directory>src/main/meta</directory>
            <includes>
              <include>findbugs.xml</include>
              <include>messages.xml</include>
              <include>bugrank.txt</include>
            </includes>
          </resource>
        </resources>
      </build>
    </profile>
  </profiles>