SLF4J用PMDルールセットの実装に限界が見えたのでFindBugsに乗り換えました。で、FingBugsプラグイン実装関連の日本語情報がわりとないようなので、試行錯誤の過程を残しておきます。まだ自分も完全にはできていないので、情報をお持ちでしたらぜひご指摘ください。
やるべきこと
参考情報
整理された情報はほぼ無いのでコードを読むのが手っ取り早い。非公式だがfb-contribのコードも参考になる。
- Detectorの実装例
- 公式Wiki
- 非公式情報
- FindBugs 第2回: カスタムのチェック機能を書く
- fb-contrib(GitHubの方が便利、Antベースだが参考になる)
- Writing new FindBugs detectors(PDF、参考になるか微妙)
テストケース実装
コードとwikiを読む限りでは以下の様な機構が用意されているようだがまだ使っていない。そもそもプラグイン開発に流用できるのか不明。
- バグを表す最小限のクラスをテストケースとして用いる
- 期待するバグを@ExpectWarningアノテーションで明示
- バグとして判断すべきでないケースもテストケースとして追加する場合は@NoWarningアノテーションを用いる
Detectorの実装
- BytecodeScanningDetectorとかByteCodePatternDetectorとかを継承するのが普通?今回はオペランドスタックを重視したパターンなのでOpcodeStackDetectorを継承。
- BytecodeScanningDetectorを使うならDismantleBytecodeに定義されている便利メソッドを眺めておくと良い。
- BugReporterを1つ受け取るpublicなコンストラクタを実装する必要がある。
パッケージの作成
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>