# &FindBugs;™ マニュアル

David
H.
Hovemeyer
William
W.
Pugh
2003
2004
2005
2006
2008
University of Maryland

このマニュアルは、クリエイティブ・コモンズ表示-非営利-継承に基づく使用許諾がなされています。使用許諾書をご覧になる場合は、 http://creativecommons.org/licenses/by-nc-sa/1.0/ にアクセスするか、クリエイティブ・コモンズ(559 Nathan Abbott Way, Stanford, California 94305, USA)に書簡を送付してください。

名称「FindBugs」および FindBugs のロゴは、メリーランド大学の登録商標です。

1.3.9
16:39:49 EDT, 21 August, 2009

## はじめに

&FindBugs;™ は、Java プログラムの中のバグを見つけるプログラムです。このプログラムは、「バグ パターン」の実例を探します。「バグ パターン」とは、エラーとなる可能性の高いコードの事例です。

この文書は、&FindBugs; バージョン 1.3.9 について説明してます。私たちは、 &FindBugs; に対するフィードバックを心待ちにしています。どうぞ、 &FindBugs; Web ページ にアクセスしてください。&FindBugs; についての最新情報、連絡先および &FindBugs; メーリングリストなどのサポート情報を入手することができます。

### 必要条件

&FindBugs; を使用するには、 Java 2 Standard Edition, バージョン 1.5 以降のバージョンと互換性のあるランタイム環境が必要です。&FindBugs; は、プラットフォーム非依存であり、 GNU/Linux 、 Windows 、 MacOS X プラットフォーム上で動作することが知られています。

&FindBugs; を使用するためには、少なくとも 512 MB のメモリが必要です。巨大なプロジェクトを解析するためには、それより多くのメモリが必要とされることがあります。

## &FindBugs;™ のインストール

この章では、 &FindBugs; のインストール方法を説明します。

### 配布物の展開

&FindBugs; をインストールする最も簡単な方法は、バイナリ配布物をダウンロードすることです。 バイナリ配布物は、 gzipped tar 形式 および zip 形式 がそれぞれ入手可能です。バイナリ配布物をダウンロードしてきたら、それを任意のディレクトリーに展開します。

gzipped tar 形式配布物の展開方法例:

    $ gunzip -c findbugs-1.3.9.tar.gz | tar xvf -

zip 形式配布物の展開方法例:

    C:\Software>unzip findbugs-1.3.9.zip

バイナリ配布物の展開すると、通常は `findbugs-1.3.9` ディレクトリーが作成されます。例えば、ディレクトリー `C:\Software` でバイナリ配布物を展開すると、ディレクトリー `C:\Software\findbugs-1.3.9` に &FindBugs; は展開されます。このディレクトリーが &FindBugs; のホームディレクトリーになります。このマニュアルでは、このホームディレクトリーを &FBHome; (Windowsでは &FBHomeWin;) を用いて参照します。

## &FindBugs;™ のソールからのビルド

この章では、 &FindBugs; をソースコードからビルドする方法を説明します。&FindBugs; を修正することに興味がないのであれば、 次の章 に進んでください。

### 前提条件

ソースから &FindBugs; をコンパイルするためには、以下のものが必要です。

- &FindBugs; のソース配布物

- JDK 1.5.0 ベータ またはそれ以降

- Apache &Ant;, バージョン 1.6.3 またはそれ以降

Redhat Linux システムの `/usr/bin/ant` に同梱されている &Ant; のバージョンでは、 &FindBugs; のコンパイルはうまくできません。&Ant; web サイトからバイナリ配布物をダウンロードしてインストールすることを推奨します。&Ant; を実行する場合は、 環境変数 JAVA_HOME が JDK 1.5 (またはそれ以降)をインストールしたディレクトリーを指していることを確認してください。

体裁の整った &FindBugs; のドキュメントを生成したい場合は、以下のソフトウェアも必要となります:

- DocBook XSL スタイルシート。&FindBugs; のマニュアルを HTML に変換するのに必要です。

- &Saxon; XSLT プロセッサー。(同様に、 &FindBugs; のマニュアルを HTML に変換するのに必要です。)

### ソース配布物の展開

ソース配布物をダウンロードした後に、それを作業用ディレクトリーに展開する必要があります。通常は、次のようなコマンドで展開を行います:

    $ unzip findbugs-1.3.9-source.zip

### `local.properties` の修正

FindBugs のドキュメントをビルドするためには、 `local.properties` ファイルを修正する必要があります。このファイルは、 &FindBugs; をビルドする際に &Ant; `build.xml` ファイルが参照します。FindBugs のドキュメントをビルドしない場合は、このファイルは無視してもかまいません。

`local.properties` での定義は、 `build.properties` ファイルでの定義に優先します。`build.properties` は次のような内容です:

    # User Configuration:
    # This section must be modified to reflect your system.

    local.software.home     =/export/home/daveho/linux

    # Set this to the directory containing the DocBook Modular XSL Stylesheets
    #  from http://docbook.sourceforge.net/projects/xsl/

    xsl.stylesheet.home     =${local.software.home}/docbook/docbook-xsl-1.71.1

    # Set this to the directory where Saxon (http://saxon.sourceforge.net/)
    # is installed.

    saxon.home              =${local.software.home}/java/saxon-6.5.5

`xsl.stylesheet.home` プロパティーには、DocBook Modular XSL スタイルシートがインストールしてあるディレクトリーの絶対パスを指定します。&FindBugs; ドキュメントを生成しようと考えている場合にのみ、このプロパティーを指定する必要があります。

`saxon.home` プロパティーには、&Saxon; XSLT プロセッサーがインストールしてあるディレクトリーの絶対パスを指定します。&FindBugs; ドキュメントを生成しようと考えている場合にのみ、このプロパティーを指定する必要があります。

### &Ant; の実行

ソース配布物の展開、 &Ant; のインストール、`build.properties`(`local.properties`) の修正 (これは任意) およびツール (&Saxon; など)の環境構築ができれば、 &FindBugs; をビルドするための準備は完了です。&Ant; の起動する方法は、単にコマンドを実行するだけです。

    $ ant target

target には以下のいずれかを指定します:

`build`

  このターゲットは、 &FindBugs; のコードをコンパイルします。これは、デフォルトのターゲットです。

`docs`

  このターゲットは、ドキュメントの整形を行います(また、副作用としていくつかのソースのコンパイルも行います。)

`runjunit`

  このターゲットは、コンパイルを行い &FindBugs; が持っている JUnit テストを実行します。ユニットテストが失敗した場合は、エラーメッセージが表示されます。

`bindist`

  &FindBugs; のバイナリ配布物を構築します。このターゲットは、 `.zip` および `.tar.gz` のアーカイブをそれぞれ作成します。

&Ant; コマンドの実行後、次のような出力が表示されるはずです。 (この前に &Ant; が実行したタスクに関するメッセージもいくらか出力されます。):

    BUILD SUCCESSFUL
    Total time: 17 seconds

### ソースディレクトリーからの &FindBugs;™ の実行

`build` ターゲットの実行が終了すると、バイナリ配布物と同様の状態が作業ディレクトリーに構築されるように &FindBugs; の&Ant; ビルドスクリプトは記述されています。したがって、 の &FindBugs; の実行に関する情報はソース配布物の場合にも応用できます。

## &FindBugs;™ の実行

&FindBugs; には2つのユーザーインタフェースがあります。すなわち、グラフィカルユーザーインタフェース (GUI) および コマンドラインインタフェースです。この章では、それぞれのインタフェースの実行方法について説明します。

この章は、現在書き直し中です。書き直しはまだ完了していません。

### クイック・スタート

Windows システムで &FindBugs; を起動する場合は、 `&FBHomeWin;\lib\findbugs.jar` ファイルをダブルクリックしてください。 &FindBugs; GUI が起動します。

Unix 、 Linux または Mac OS X システムの場合は、`&FBHome;/bin/findbugs` スクリプトを実行するか、以下のコマンドを実行します。

    java -jar &FBHome;/lib/findbugs.jar

これで、 &FindBugs; GUI が起動します。

GUI の使用方法については、 を参照してください。

### &FindBugs; の起動

このセクションでは、 &FindBugs; の起動方法を説明します。&FindBugs; を起動するには2つの方法があります。すなわち、直接起動する方法、および、ラップしているスクリプトを使用する方法です。

#### &FindBugs; の直接起動

最初に述べる &FindBugs; の起動方法は、 `&FBHome;/lib/findbugs.jar` を直接実行する方法です。JVM (`java`) 実行プログラムの `-jar` コマンドラインスイッチを使用します。(&FindBugs;のバージョンが 1.3.5 より前の場合は、ラップしているスクリプトを使用する必要があります。)

&FindBugs; を直接起動するための、一般的な構文は以下のようになります。

    	java [JVM 引数] -jar &FBHome;/lib/findbugs.jar オプション…

##### ユーザーインタフェースの選択

1 番目のコマンドラインオプションは、起動する &FindBugs; ユーザーインタフェースを選択するためのものです。指定可能な値は次の通りです:

- `-gui`: グラフィカルユーザーインタフェース (GUI) を起動します。

- `-textui`: コマンドラインインタフェースを起動します。

- `-version`: &FindBugs; のバージョン番号を表示します。

- `-help`: &FindBugs; コマンドラインインタフェースのヘルプ情報を表示します。

- `-gui1`: 最初に作成された &FindBugs; グラフィカルユーザーインタフェース(すでに廃止されサポートされていない)を起動します。

##### Java 仮想マシン (JVM) 引数

&FindBugs; を起動する際に有用な Java 仮想マシン 引数をいくつか紹介します。

`-XmxNNm`

  Java ヒープサイズの最大値を NN メガバイトに設定します。&FindBugs; は一般的に大容量のメモリサイズを必要とします。大きなプロジェクトでは、 1500 メガバイトを使用することも珍しくありません。

`-Dname=value`

  Java システムプロパティーを設定します。例えば、引数 `-Duser.language=ja` を使用すると GUI 文言が日本語で表示されます。

#### ラップしているスクリプトを使用した &FindBugs; の起動

&FindBugs; を起動するもうひとつの方法は、ラップしているスクリプトを使用する方法です。

Unix 系のシステムにおいては、次のようなコマンドでラップしているスクリプトを起動します :

    $ &FBHome;/bin/findbugs オプション…

Windows システムにおいては、ラップしているスクリプトを起動するコマンドは次のようになります。

    C:\My Directory>&FBHomeWin;\bin\findbugs.bat オプション…

Unix 系システム および Windows システムのどちらにおいても、ディレクトリー `$FINDBUGS_HOME/bin` を環境変数 `PATH` に追加するだけで、 `findbugs` コマンドを使用して FindBugs を起動することができます。

##### ラップしているスクリプトのコマンドラインオプション

&FindBugs; のラップしているスクリプトは、次のようなコマンドラインオプションをサポートしています。これらのコマンドラインオプションは &FindBugs; プログラム 自体が操作するのではなく、どちらかといえば、ラップしているスクリプトの方が処理を行います。

`-jvmArgs 引数`

  JVM に受け渡される引数を指定します。例えば、次のような JVM プロパティが設定できます:

      $ findbugs -textui -jvmArgs "-Duser.language=ja" myApp.jar

`-javahome ディレクトリー`

  &FindBugs; の実行に使用する JRE (Java ランタイム環境) がインストールされているディレクトリーを指定します。

`-maxHeap サイズ`

  Java ヒープサイズの最大値をメガバイト単位で指定します。デフォルトは、 256 です。巨大なプログラムやライブラリを分析するには、もっと大きなメモリー容量が必要になる可能性があります。

`-debug`

  ディテクタ実行およびクラス分析のトレース情報が標準出力に出力されます。分析が予期せず失敗した際の、トラブルシューティングに有用です。

`-property` name=value

  このオプションを使用してシステムプロパティーを設定することができます。 &FindBugs; はシステムプロパティーを使用して分析特性の設定を行います。 を参照してください。このオプションを複数指定して、複数のシステムプロパティを設定することが可能です。注: Windows の多くのバージョンでは、 name=value 文字列を引用符で囲む必要があります。

### コマンドラインオプション

このセクションでは、 &FindBugs; がサポートするコマンドラインオプションについて説明します。ここで示すコマンドラインオプションは、 &FindBugs; 直接起動、または、ラップしているスクリプトによる起動で使用できます。

#### 共通のコマンドラインオプション

ここで示すオプションは、 GUI および コマンドラインインタフェースの両方で使用できます。

`-effort:min`

  このオプションを指定すると、精度を上げるために大量のメモリーを消費する分析が無効になります。&FindBugs; の実行時にメモリー不足になったり、分析を完了するまでに異常に長い時間がかかる場合に試してみてください。

`-effort:max`

  精度が高く、より多くのバグを検出する分析を有効にします。ただし、多くのメモリー容量を必要とし、また、完了までの時間が多くかかる可能性があります。

`-project` project

  分析するプロジェクトを指定します。指定するプロジェクトファイルには、 GUI を使って作成したものを使用してください。ファイルの拡張子は、一般的には `.fb` または `.fbp` です。

#### GUI オプション

ここで示すオプションは、グラフィカルユーザーインタフェースでのみ使用できます。

`-look:`plastic|gtk|native

  Swing のルック・アンド・フィールを設定します。

#### テキストユーザーインタフェースオプション

ここで示すオプションは、テキストユーザーインタフェースでのみ使用できます。

`-sortByClass`

  報告されるバグ検索結果をクラス名でソートします。

`-include` filterFile.xml

  filterFile.xml で指定したフィルターに一致したバグ検索結果のみ報告されます。 を参照してください。

`-exclude` filterFile.xml

  filterFile.xml で指定したフィルターに一致したバグ検索結果は報告されません。 を参照してください。

`-onlyAnalyze` com.foobar.MyClass,com.foobar.mypkg.*

  コンマ区切りで指定したクラスおよびパッケージのみに限定して、バグ検出の分析を行うようにします。フィルターと違って、このオプションを使うと一致しないクラスおよびパッケージに対する分析の実行を回避することができます。大きなプロジェクトにおいて、このオプションを活用すると分析にかかる時間を大きく削減することができる可能性があります。(しかしながら、アプリケーションの全体で実行していないために不正確な結果を出してしまうディテクタがある可能性もあります。) クラスはパッケージも含んだ完全な名前を指定する必要があります。また、パッケージは、 Java の `import` 文でパッケージ下のすべてのクラスをインポートするときと同じ方法で指定します。 (すなわち、パッケージの完全な名前に `.*` を付け加えた形です。)`.*` の代わりに `.-` を指定すると、サブパッケージも含めてすべてが分析されます。

`-low`

  すべてのバグが報告されます。

`-medium`

  優先度 (中) および優先度 (高) のバグが報告されます。これは、デフォルトの設定値です。

`-high`

  優先度 (高) のバグのみが報告されます。

`-relaxed`

  手抜き報告モードです。このオプションを指定すると、多くのディテクタにおいて 誤検出を回避するためのヒューリスティック機能が抑止されます。

`-xml`

  バグ報告が XML で作成されます。作成された XML データは 、後で GUI で見ることができます。このオプションは `-xml:withMessages` と指定することもできます。こうすると 出力 XML には 各バグに関して人間に読むことができるメッセージが含まれるようになります。このオプションで作成された XML ファイルは 報告書に変換するのが簡単です。

`-html`

  HTML 出力が生成されます。デフォルトでは &FindBugs; は `default.xsl` XSLT スタイルシートを使用して HTML 出力を生成します: このファイルは、 `findbugs.jar` の中、または、 &FindBugs; のソース配布物もしくはバイナリ配布物の中にあります。このオプションには、次のようなバリエーションも存在します。すなわち、 `-html:plain.xsl` 、 `-html:fancy.xsl` および `-html:fancy-hist.xsl` です。`plain.xsl` スタイルシートは Javascript や DOM を利用しません。したがって、古いWeb ブラウザ使用時や印刷時にも比較的うまく表示されるでしょう。`fancy.xsl` スタイルシートは DOM と Javascript を利用してナビゲーションを行います。また、ビジュアル表示に CSS を使用します。`fancy-hist.xsl` は `fancy.xsl` スタイルシートを更に進化させたものです。DOM や Javascript をふんだんに駆使して、バグの一覧を動的にフィルタリングします。

  ユーザー自身の XSLT スタイルシートを用いて HTML への変換を行いたい場合は、 `-html:myStylesheet.xsl` のように指定してください。ここで、 myStylesheet.xsl はユーザーが使用したいスタイルシートのファイル名です。

`-emacs`

  バグ報告が Emacs 形式で作成されます。

`-xdocs`

  バグ報告が xdoc XML 形式で作成されます。Apache Mavenで使用できます。

`-output` ファイル名

  指定したファイルに出力結果が作成されます。

`-outputFile` ファイル名

  この引数は、使用すべきではありません。代わりに、 `-output` を使用してください。

`-nested`[:true|false]

  このオプションは、ファイルやディレクトリーの中で入れ子になった jar および zip ファイルを分析するかどうかを指定します。デフォルトでは、入れ子になった jar および zip ファイルも分析します。入れ子になった jar および zip ファイルの分析するを無効にする場合は、 `-nested:false` をコマンドライン引数に追加してください。

`-auxclasspath` クラスパス

  分析時に使用する補助クラスパスを設定します。分析するプログラムで使用するjarファイルやクラスディレクトリーをすべて指定してください。補助クラスパスに指定したクラスは分析の対象にはなりません。

## &FindBugs; GUI の使用方法

この章では、&FindBugs; グラフィカルユーザーインタフェース (GUI) の使用方法を説明します。

### プロジェクトの作成

`findbugs` コマンドで &FindBugs; を起動してから、メニューで File New Project を選択してください。そうすると、次のようなダイアログが表示されます:

「Class archives and directories to analyze」テキストフィールドの横にある 「Add」ボタンを押すと、バグを分析する java クラスを含んでいる Java アーカイブファイル (zip, jar, ear, or war file) を選択して指定できます。複数の アーカイブ/ディレクトリーを追加することが可能です。

また、分析を行う Java アーカイブのソースコードを含んだソースディレクトリーを指定することもできます。そうすると、バグの可能性があるソースコードの場所が、&FindBugs; 上でハイライトして表示されます。ソースディレクトリーは、Java パッケージ階層のルートディレクトリーを指定する必要があります。例えば、ユーザのアプリケーションが `org.foobar.myapp` パッケージの中にある場合は、 `org` ディレクトリーの親ディレクトリーをソースディレクトリーリストに指定する必要があります。

もうひとつ、任意指定の手順があります。それは、補助用の Jar ファイルおよびディレクトリーを 「Auxiliary classpath locations」のエントリーに追加することです。分析するアーカイブ/ディレクトリーにも標準の実行時クラスパスにも含まれていないクラスを、分析するアーカイブ/ディレクトリーが参照している場合は、この項目を設定した方がいいでしょう。クラス階層に関する情報を使用するバグディテクタが、 &FindBugs; にはいくつかあります。したがって、&FindBugs; が分析を行うクラスの完全なクラス階層を参照できれば、より正確な分析結果を取得することができます。

### 分析の実行

アーカイブ、ディレクトリーおよびソースディレクトリーの指定ができれば、「Finish」ボタンを押して Jar ファイルに含まれるクラスに対する分析を実行します。巨大なプロジェクトを古いコンピュータ上で実行すると、かなりの時間(数十分)がかかることに注意してください。大容量メモリである最近のコンピュータなら、大きなプログラムであっても数分程度で分析できます。

### 結果の閲覧

分析が完了すると、次のような画面が表示されます :

左上のペインにはバグ階層ツリーが表示されます。これは、分析でみつかったバグの検索結果が階層的に表示されたものです。

上部のペインでバグ検索結果を選択すると、下部の「Details」ペインにバグの詳細説明が表示されます。更に、ソースがみつかれば、右上のソースコードペインにバグの出現箇所に該当するソースコードが表示されます。上図の例で表示されているバグは、ストリームオブジェクトがクローズされていないというものです。ソースコード・ウィンドウにおいて当該ストリームオブジェクトを生成している行がハイライトされています。

バグの検索結果に対してテキストで注釈を入れることができます。階層ツリー図のすぐ下にあるテキストボックスに注釈を入力してください。記録しておきたい情報を何でも自由に入力することができます。バグ結果ファイルの保存および読み込みを行ったときに、注釈も保存されます。

### 保存と読み込み

メニュー項目から File Save as... を選択すると、ユーザーの作業結果を保存することができます。「Save as...」ダイアログにあるドロップダウン・リストの中から「FindBugs analysis results (.xml)」を選択ことで、ユーザーが指定した jar ファイルリストやバグ検索結果などの作業結果を保存することができます。また、jar ファイルリストのみを保存する選択肢 (「FindBugs project file (.fbp)」) やバグ検索結果のみを保存する選択肢 (「FindBugs analysis file (.fba)」) もあります。保存したファイルは、メニュー項目から File Open... を選択することで、読み込むことができます。

## &FindBugs;™ &Ant; タスクの使用方法

この章では、 &FindBugs; を &Ant; のビルドスクリプトに組み入れる方法について説明します。 &Ant; は、ビルドや配備を行うことができる Java でよく使用されるツールです。&FindBugs; &Ant; タスクを使用すると、 ビルドスクリプトを作成して機械的に &FindBugs; による Java コードの分析を実行することができます。

この &Ant; タスクは、 Mike Fagan 氏の多大な貢献によるものです。

### &Ant; タスクのインストール

&Ant; タスクのインストールは、 `&FBHome;/lib/findbugs-ant.jar` を &Ant; インストールディレクトリーの`lib` サブディレクトリーにコピーするだけです。

使用する &Ant; タスクと &FindBugs; 本体は、同梱されていた同じバージョンのものを使用することを強く推奨します。別のバージョンの &FindBugs; に含まれていた &Ant; タスク Jar ファイルでの動作は保証しません。

### build.xml の書き方

&FindBugs; を `build.xml` (&Ant; ビルドスクリプト) に組み入れるためにはまず、タスク定義を記述する必要があります。タスク定義は次のように記述します。:

      <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"/>

タスク定義は、 `findbugs` 要素を `build.xml` 上に記述したとき、そのタスクの実行に使用されるクラスを指定します。

タスク定義の記述をすれば、`findbugs` タスクを使ってターゲットを定義できます。次に示すのは、 Apache BCEL ライブラリーを分析する場合を想定した `build.xml` の記述例です。

      <property name="findbugs.home" value="/export/home/daveho/work/findbugs" />

      <target name="findbugs" depends="jar">
        <findbugs home="${findbugs.home}"
                  output="xml"
                  outputFile="bcel-fb.xml" >
          <auxClasspath path="${basedir}/lib/Regex.jar" />
          <sourcePath path="${basedir}/src/java" />
          <class location="${basedir}/bin/bcel.jar" />
        </findbugs>
      </target>

`findbugs` 要素には、 `home` 属性が必須です。 &FindBugs; のインストールディレクトリーすなわち &FBHome; の値を設定します。 を参照してください。

このターゲットは `bcel.jar` に対して &FindBugs; を実行します。この Jar ファイルは、 BCEL ビルドスクリプトによって作成されるものです。(上記のターゲットが「jar」ターゲットに依存している (depends) と設定することにより、 &FindBugs; が実行される前に当該ライブラリーが完全にコンパイルされていることを保証しています。) &FindBugs; の出力は、 XML 形式で `bcel-fb.xml` ファイルに保存されます。補助 Jar ファイル `Regex.jar` を aux classpath に記述しています。なぜなら、当該 Jar ファイルが BCEL メイン･ライブラリーから参照されるからです。source path を指定することで、保存されるバグデータに BCEL ソースコードへの正確な参照が記述されます。

### タスクの実行

コマンドラインから &Ant; を起動する例を次に示します。前述の `findbugs` ターゲットを使用しています。

      [daveho@noir]$ ant findbugs
      Buildfile: build.xml

      init:

      compile:

      examples:

      jar:

      findbugs:
       [findbugs] Running FindBugs...
       [findbugs] Bugs were found
       [findbugs] Output saved to bcel-fb.xml

      BUILD SUCCESSFUL
      Total time: 35 seconds

この事例においては、XML ファイルでバグ検索結果を保存しているので、 &FindBugs; GUI を使って結果を参照することができます。 を参照してください。

### パラメーター

このセクションでは、 &FindBugs; タスクを使用する際に、指定することができるパラメーターについて説明します。

`class`

  分析の対象となるクラス群を指定するためのネストされる要素です。`class` 要素には `location` 属性の指定が必須です。分析対象となるアーカイブファイル (jar, zip, 他)、ディレクトリーまたはクラスファイルの名前を記述します。1 つの `findbugs` 要素に対して、複数の `class` 子要素を指定することができます。

`auxClasspath`

  任意指定のネストされる要素です。分析対象のライブラリーまたはアプリケーションによって使用されているが分析の対象にはしたくないクラスを含んでいるクラスパス (Jar ファイルまたはディレクトリー) を指定します。 &Ant; の Java タスクにある `classpath` 要素 と同じ方法で指定することができます。

`sourcePath`

  任意指定のネストされる要素です。分析対象 Java コードのコンパイル時に使用したソースファイルを含んでいるソースディレクトリーへのパスを指定します。ソースパスを指定することにより、生成される XML のバグ出力結果に完全なソース情報をもたせることができ、後になって GUI で参照することができます。

`home`

  必須属性です。&FindBugs; がインストールされているディレクトリー名を設定します。

`quietErrors`

  任意指定のブール値属性です。true を設定すると、深刻な分析エラー発生やクラスがみつからないといった情報が &FindBugs; 出力に記録されません。デフォルトは、 false です。

`reportLevel`

  任意指定の属性です。報告されるバグの優先度のしきい値を指定します。「low」に設定すると、すべてのバグが報告されます。「medium」 (デフォルト) に設定すると、優先度 (中)および優先度 (高)のバグが報告されます。「high」に設定すると、優先度 (高) のバグのみが報告されます。

`output`

  任意指定の属性です。出力形式を指定します。「xml」 (デフォルト) に設定すると、出力は XML 形式になります。「xml:withMessages」 に設定すると、出力は人間が読めるメッセージ が追加された XML 形式になります。(XSL スタイルシートを使ってレポートを作成することを計画している場合はこの形式を使用してください。) 「html」に設定すると、出力は HTML 形式(デフォルトのスタイルシートは default.xsl) になります。 「text」に設定すると、出力は特別なテキスト形式になります。「emacs」に設定すると、出力は Emacs エラーメッセージ形式になります。「xdocs」に設定すると、出力は Apache Maven で使用できる xdoc XML になります。

`stylesheet`

  任意指定の属性です。output 属性 に html を指定した場合に、 HTML 出力作成に使用されるスタイルシートを指定します。FindBugs 配布物に含まれているスタイルシートは、 default.xsl、 fancy.xsl 、 fancy-hist.xsl 、 plain.xsl および summary.xsl です。デフォルト値は default.xsl です。

`sort`

  任意指定の属性です。`output` 属性に「text」を指定した場合に、バグの報告をクラス順にソートするかどうかを `sort` 属性で指定します。デフォルトは、 true です。

`outputFile`

  任意指定の属性です。指定した場合、&FindBugs; の出力はその名前のファイルへと保存されます。省略時、出力は &Ant; によって直接表示されます。

`debug`

  任意指定のブール値属性です。true に設定すると、 &FindBugs; は 診断情報を出力します。どのクラスを分析しているか、どのパグパターンディテクタが実行されているか、という情報が表示されます。デフォルトは、 false です。

`effort`

  分析の活動レベルを設定します。`min` 、`default` または `max` のいずれかの値を設定してください。分析レベルの設定に関する詳細情報は、 を参照してください。

`conserveSpace`

  effort="min" と同義です。

`workHard`

  effort="max" と同義です。

`visitors`

  任意指定の属性です。どのバグディテクタを実行するかをコンマ区切りのリストで指定します。バグディテクタはパッケージ指定なしのクラス名で指定します。省略時、デフォルトで無効化されているものを除くすべてのディテクタが実行されます。

`omitVisitors`

  任意指定の属性です。`visitors` 属性と似ていますが、こちらは 実行されない ディテクタを指定します。

`excludeFilter`

  任意指定の属性です。フィルターファイル名を指定します。報告から除外されるバグを指定します。 を参照してください。

`includeFilter`

  任意指定の属性です。フィルターファイル名を指定します。報告されるバグを指定します。 を参照してください。

`projectFile`

  任意指定の属性です。プロジェクトファイル名を指定します。プロジェクトファイルは、 &FindBugs; GUI で作成します。分析されるクラス、および、補助クラスパス、ソースディレクトリーが記入されてます。プロジェクトファイルを指定した場合は、 `class` 要素・ `auxClasspath` 属性および `sourcePath` 属性を設定する必要はありません。プロジェクトの作成方法は、 を参照してください。

`jvmargs`

  任意指定の属性です。&FindBugs; を実行している Java 仮想マシンに対して受け渡される引数を指定します。巨大なプログラムを分析する場合に、 JVM が使用するメモリ容量を増やす指定をするためにこの引数を利用する必要があるかもしれません。

`systemProperty`

  任意指定のネストされる要素です。指定した場合、Java システムプロパティーを定義します。`name` 属性にはシステムプロパティーの名前を指定します。そして、 `value` 属性にはシステムプロパティの値を指定します。

`timeout`

  任意指定の属性です。&FindBugs; を実行している Java プロセス の実行許容時間をミリ秒単位で指定します。時間を超過するとハングアップしていると判断してプロセスが終了されます。デフォルトは、 600,000 ミリ秒 (10 分) です。巨大なプログラムの場合は、 &FindBugs; が分析を完了するまでに 10 分 以上掛かる可能性があることに注意してください。

`failOnError`

  任意指定のブール値属性です。&FindBugs; の実行中にエラーがあった場合に、ビルドプロセス自体を打ち切って異常終了させるかどうかを指定します。デフォルトは、「false」です。

`errorProperty`

  任意指定の属性です。&FindBugs; の実行中にエラーが発生した場合に、「true」が設定されるプロパティーの名前を指定します。

`warningsProperty`

  任意指定の属性です。&FindBugs; が分析したプログラムにバグ報告が 1 件でもある場合に、「true」が設定されるプロパティーの名前を指定します。

## &FindBugs;™ Eclipse プラグインの使用方法

FindBugs Eclipse プラグインを使用することによって、 &FindBugs; を Eclipse IDE で使用することができるようになります。このFindBugs Eclipse プラグインは、 Peter Friese 氏の多大な貢献によるものです。Phil Crosby 氏 と Andrei Loskutov 氏は、プラグインの重要な改良に貢献しました。

### 必要条件

&FindBugs; Eclipse Plugin を使用するためには、 Eclipse 3.3 あるいはそれ以降のバージョン、また、 JRE/JDK 1.5 あるいはそれ以降のバージョンが必要です。

### インストール

更新サイトが提供されています。更新サイトを利用して、機械的に FindBugs を Eclipse にインストールできます。また自動的に、最新版のアップデートを照会してインストールすることもできます。内容の異なる 3 つの更新サイトが存在します。

#### FindBugs Eclipse 更新サイト一覧

http://findbugs.cs.umd.edu/eclipse/

  FindBugs の公式リリース物を提供します。

http://findbugs.cs.umd.edu/eclips-candidate/

  FindBugsの公式リリース物に加えて、公式リリース候補版を提供します。

http://findbugs.cs.umd.edu/eclipse-daily/

  FindBugsの日次ビルド物を提供します。コンパイルができること以上のテストは行われていません。

また、次に示すリンクから手動でプラグインをダウンロードすることもできます : http://prdownloads.sourceforge.net/findbugs/edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821.zip?download. 展開して Eclipse の「plugins」サブディレクトリーに入れてください。(そうすると、 <eclipse インストールディレクトリー >/plugins/edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821/findbugs.png が &FindBugs; のロゴファイルへのパスになるはずです。)

プラグインの展開ができたら、 Eclipse を起動して Help About Eclipse Platform Plug-in Details を選択してください。「FindBugs Project」から提供された「FindBugs Plug-in」というプラグインがあることを確認してください。

### プラグインの使用方法

実行するには、 Java プロジェクト上で右クリックして「Find Bugs」を選択します。&FindBugs; が実行されて、バグパターンの実例の可能性があると識別されたコード箇所に問題マーカーがつきます。 (ソース画面および Eclipse 問題ビューに表示されます。)

Java プロジェクトのプロパティーダイアログを開いて「Findbugs」プロパティーページを選択することで、 &FindBugs; の動作をカスタマイズすることができます。選択できる項目には次のようなものがあります :

- 「Run FindBugs Automatically」チェックボックスの設定。チェックすると、プロジェクト内の Java クラスが修正されるたびに FindBugs が実行されます。

- 優先度とバグカテゴリーの選択。これらのオプションは、どの警告を表示するかを選択します。例えば、優先度で 「Medium」 を選択すると、優先度 (中) および優先度 (高) の警告のみが表示されます。同様に、「Style」チェックボックスのチェックマークを外すと、Style カテゴリーに属する警告は表示されません。

- ディテクタの選択。表からプロジェクトで有効にしたいディテクタを選択することができます。

### トラブルシューティング

&FindBugs; Eclipse プラグインは、まだ実験段階です。このセクションでは、プラグインに関する一般的な問題と (判明していれば) それらの問題の解決方法を記述します。

- &FindBugs; 問題マーカーが (ソース画面および問題ビューに) 表示されない場合は、問題ビューのフィルター設定を変更してください。詳細情報は http://findbugs.sourceforge.net/FAQ.html#q7 を参照してください。

## フィルターファイル

フィルターファイルを使用することで、特定のクラスやメソッドをバグ報告に含めたりバグ報告から除外したりすることができます。この章では、フィルターファイルの使用方法を説明します。

### 計画されている機能

フィルターは現在、コマンドラインインタフェースでのみサポートされています。最終的には、フィルターのサポートは GUI にも追加される予定です。

### フィルターファイルの概要

概念的に言えば、フィルターはバグ検索結果をある基準と照合します。フィルターを定義することで、 特別な取り扱いをするバグ検索結果を選択することができます。例えば、あるバグ検索結果をバグ報告に含めたり、バグ報告から除外したりすることができます。

フィルターファイルは、 XML 文書です。最上位要素が`FindBugsFilter` 要素 であり、その子要素として `Match` 要素を複数個定義します。それぞれの `Match` 要素は、生成されたバグ検索結果に適用される述部にあたります。通常、フィルターはバグ検索結果を除外するために使用します。次に、例を示します:

    $ findbugs -textui -exclude myExcludeFilter.xml myApp.jar

また一方で、的をしぼった報告を得るためにバグ報告結果を選択するためにフィルターを使用することも考えられます :

    $ findbugs -textui -include myIncludeFilter.xml myApp.jar

`Match` 要素は子要素を持ちます。それらの子要素は論理積で述部になります。つまり、述部が真であるためには、すべての子要素が真である必要があります。

### マッチング条件の種類

`<Bug>`

  この要素は、バグパターンを指定して照合します。`pattern` 属性には、コンマ区切りでバグパターン類型のリストを指定します。どの警告がどのバグパターン類型にあたるかは、 `-xml` オプションをつかって出力されたもの (`BugInstance` 要素の `type` 属性) を見るか、または、 バグ解説ドキュメントを参照してください。

  もっと粒度の粗い照合を行いたいときは、 `code` 属性を使用してください。バグ略称のコンマ区切りのリストで指定できます。さらに粒度の粗い照合を行いたいときは、 `category` 属性を使用してください。次に示す、バグカテゴリー名のコンマ区切りのリストで指定できます : `CORRECTNESS`, `MT_CORRECTNESS`, `BAD_PRACTICICE`, `PERFORMANCE`, `STYLE`.

  同じ `<Bug>` 要素に上記の属性を複数指定した場合は、バグパターン名、バグ略称、バグカテゴリーのいずれか1つでも該当すれば、バグパターンは合致すると判定されます。

  下位互換性を持たせたい場合は、 `<Bug>` 要素の代わりに `<BugPattern>` 要素および `<BugCode>` 要素を使用してください。これらの要素はそれぞれ、 `name` 属性で値のリストを指定します。これらの要素は、将来サポートされなくなる可能性があります。

`<Priority>`

  この要素は、特定の優先度をもつ警告を照合します。`value` 属性には、整数値を指定します : 1 は優先度(高)、また、 2 は優先度(中) 、 3 は優先度(低) を示します。

`<Package>`

  この要素は、 `name` 属性で指定した特定のパッケージ内にあるクラスに関連した警告を照合します。入れ子のパッケージは含まれません (Java import 文に従っています) 。しかしながら、正規表現を使うと複数パッケージにマッチさせることは簡単にできます。

`<Class>`

  この要素は、特定のクラスに関連した警告を照合します。`name` 属性を使用して、照合するクラス名をクラス名そのものか、または、正規表現で指定します。

  下位互換性を持たせたい場合は、この要素の代わりに `Match` 要素を使用してください。クラス名そのものの指定は `class` 属性を、クラス名を正規表現で指定する場合は `classregex` 属性をそれぞれ使用してください

  もし `Match` 要素に `Class` 要素が無かったり、 `class` / `classregex` 属性が無かったりした場合は、すべてのクラスに適用されます。その場合、想定外に多くのバグ検索結果が一致してしまうことがあり得ます。その場合は、適当なメソッドやフィールドで絞り込んでください。

`<Method>`

  この要素は、メソッドを指定します。`name` 属性を使用して、照合するメソッド名をメソッド名そのものか、または、正規表現で指定します。`params` 属性には、コンマ区切りでメソッド引数の型のリストを指定します。`returns` 属性にはメソッドの戻り値の型を指定します。`params` および `returns` においては、クラス名は完全修飾名である必要があります。(例えば、単に "String" ではなく "java.lang.String" としてください。) `params` `returns` のどちらか一方を指定した場合は、もう一方の属性の指定も必須です。なぜならば、メソッドシグニチャーを構築のために必要だからです。`name` 属性、`params` 属性 および `returns` 属性または 3 つの 属性すべて、のどれかを条件とすることできることを意味しています。このように、名前とシグニチャーに基づく様々な種類の条件を規定できます。

`<Field>`

  この要素は、フィールドを指定します。`name` 属性を使用して、照合するフィールド名をフィールド名そのものか、または、正規表現で指定します。また、フィールドのシグニチャーに照らしたフィルタリングをすることができます。 `type` 属性を使用して、フィールドの型を完全修飾名で指定してください。名前とシグニチャーに基づく条件を規定するために、その2つの属性を両方とも指定することができます。

`<Local>`

  この要素は、ローカル変数を指定します。`name` 属性を使用して、照合するローカル変数名をローカル変数名そのものか、または、正規表現で指定します。ローカル変数とは、メソッド内で定義した変数です。

`<Or>`

  この要素は、論理和として `Match` 条項を結合します。すなわち、2つの `Method` 要素を `Or` 条項に入れることで、どちらか一方のメソッドでマッチさせることができます。

### Java 要素名マッチング

`Class` 、 `Method` または `Field` の `name` 属性が文字 ~ で始まっている場合は、属性値の残りの部分を Java の正規表現として解釈します。そうして、当該 Java 要素の名前に対しての照合が行われます。

パターンの照合は要素の名前全体に対して行われることに注意してください。そのため、部分一致照合を行いたい場合はパターン文字列の前後に .* を付加して使用する必要があります。

パターンの構文規則に関しては、 `java.util.regex.Pattern` のドキュメントを参照してください。

### 留意事項

`Match` 条項は、バグ検索結果に実際に含まれている情報にのみ一致します。すべてのバグ検索結果はクラスを持っています。したがって、一般的に言って、バグを除外するためにはクラスを用いて行うとうまくいくことが多いです。

バグ検索結果の中には、2個以上のクラスを保持しているものもあります。例えば、 DE (dropped exception : 例外の無視) バグは、 例外の無視が発生したメソッドを持っているクラスと、 無視された例外の型を表すクラスの両方を含んだ形で報告されます。`Match` 条項とは、 1番目 (主) のクラスのみが照合されます。したがって、例えば、クラス "com.foobar.A" 、 "com.foobar.B" 間での IC (initialization circularity : 初期化時の処理循環) バグ報告を抑止したい場合、以下に示すように 2つの `Match` 条項を使用します :

       <Match>
          <Class name="com.foobar.A" />
          <Bug code="IC" />
       </Match>

       <Match>
          <Class name="com.foobar.B" />
          <Bug code="IC" />
       </Match>

明示的に両方のクラスで照合することによって、循環しているどちらのクラスがバグ検索結果の 1 番目になっているかに関係なく一致させることができます。(もちろんこの方法は、処理循環が "com.foobar.A" 、 "com.foobar.B" に加えて3番目のクラスも含んでいる場合は図らずも失敗してしまう恐れがあります。)

多くの種類のバグ報告は、自身が出現したメソッドを報告します。それらのバグ検索結果に対しては、 `Method` 条項を `Match` 要素に加えると期待通りの動作をするでしょう。

### 例

1. 特定のクラスに対するすべてのバグ報告に一致させます。

         <Match>
           <Class name="com.foobar.MyClass" />
         </Match>

2. バグ略称を指定して、特定のクラスに対する特定の検査項目に一致させます。

         <Match>
           <Class name="com.foobar.MyClass"/ >
           <Bug code="DE,UrF,SIC" />
         </Match>

3. バグ略称を指定して、すべてのクラスに対する特定の検査項目に一致させます。

         <Match>
           <Bug code="DE,UrF,SIC" />
         </Match>

4. バグカテゴリーを指定して、すべてのクラスに対する特定の検査項目に一致させます。

         <Match>
           <Bug category="PERFORMANCE" />
         </Match>

5. バグ略称を指定して、特定のクラスの指定されたメソッドに対する特定のバグ種別に一致させます。

         <Match>
           <Class name="com.foobar.MyClass" />
           <Or>
             <Method name="frob" params="int,java.lang.String" returns="void" />
             <Method name="blat" params="" returns="boolean" />
           </Or>
           <Bug code="DC" />
         </Match>

6. 特定のメソッドに対する特定のバグパターンに一致させます。

        <!-- open stream に関する誤検出があるメソッド。-->
        <Match>
          <Class name="com.foobar.MyClass" />
          <Method name="writeDataToFile" />
          <Bug pattern="OS_OPEN_STREAM" />
        </Match>

7. 特定のメソッドに対する特定の優先度を付与された特定のバグパターンに一致させます。

        <!-- dead local store (優先度 (中)) に関する誤検出があるメソッド。-->
        <Match>
          <Class name="com.foobar.MyClass" />
          <Method name="someMethod" />
          <Bug pattern="DLS_DEAD_LOCAL_STORE" />
          <Priority value="2" />
        </Match>

8. AspectJ コンパイラーによって引き起こされるマイナーバグに一致させます (AspectJ の開発者でもない限り、それらのバグに関心を持つことはないと考えます)。

        <Match>
          <Class name="~.*\$AjcClosure\d+" />
          <Bug pattern="DLS_DEAD_LOCAL_STORE" />
          <Method name="run" />
        </Match>
        <Match>
          <Bug pattern="UUF_UNUSED_FIELD" />
          <Field name="~ajc\$.*" />
        </Match>

9. 基盤コードの特定の部分に対するバグに一致させます

        <!-- すべてのパッケージにある Messages クラスに対する unused fields 警告に一致。 -->
        <Match>
          <Class name="~.*\.Messages" />
          <Bug code="UUF" />
        </Match>
        <!-- すべての internal パッケージ内の mutable statics 警告に一致。 -->
        <Match>
          <Package name="~.*\.internal" />
          <Bug code="MS" />
        </Match>
        <!-- ui パッケージ階層内の anonymoous inner classes 警告に一致。 -->
        <Match>
          <Package name="~com\.foobar\.fooproject\.ui.*" />
          <Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON" />
        </Match>

10. 特定のシグニチャーを持つフィールドまたはメソッドのバグに一致させます。

    	<!-- すべてのクラスの main(String[]) メソッドに対する System.exit(...) usage 警告に一致。 -->
    	<Match>
    	  <Method returns="void" name="main" params="java.lang.String[]" />
    	  <Method pattern="DM_EXIT" />
    	</Match>
    	<!-- すべてのクラスの com.foobar.DebugInfo 型のフィールドに対する UuF 警告に一致。 -->
    	<Match>
    	  <Field type="com.foobar.DebugInfo" />
    	  <Bug code="UuF" />
    	</Match>

### 完全な例

    <FindBugsFilter>
         <Match>
           <Class name="com.foobar.ClassNotToBeAnalyzed" />
         </Match>

         <Match>
           <Class name="com.foobar.ClassWithSomeBugsMatched" />
           <Bug code="DE,UrF,SIC" />
         </Match>

         <!-- XYZ 違反に一致。-->
         <Match>
           <Bug code="XYZ" />
         </Match>

         <!-- "AnotherClass" の特定のメソッドの doublecheck 違反に一致。-->
         <Match>
           <Class name="com.foobar.AnotherClass" />
           <Or>
             <Method name="nonOverloadedMethod" />
             <Method name="frob" params="int,java.lang.String" returns="void" />
             <Method name="blat" params="" returns="boolean" />
           </Or>
           <Bug code="DC" />
         </Match>

         <!-- dead local store (優先度 (中)) に関する誤検出があるメソッド。-->
         <Match>
           <Class name="com.foobar.MyClass" />
           <Method name="someMethod" />
           <Bug pattern="DLS_DEAD_LOCAL_STORE" />
           <Priority value="2" />
         </Match>
    </FindBugsFilter>

## 分析プロパティー

&FindBugs; は分析する場合にいくつかの観点を持っています。そして、観点をカスタマイズして実行することができます。システムプロパティーを使って、それらのオプションを設定します。この章では、分析オプションの設定方法を説明します。

分析オプションの主な目的は、 2 つあります。1 番目は、 &FindBugs; に対して分析されるアプリケーションのメソッドの意味を伝えることです。そうすることで &FindBugs; がより正確な結果を出すことができ、誤検出を減らすことができます。2 番目に、分析を行うに当たりその精度を設定できるようにすることです。分析の精度を落とすことで、メモリ使用量と分析時間を減らすことができます。ただし、本当のバグを見逃したり、誤検出の数が増えるという代償があります。

コマンドラインオプション `-property` を使って、分析オプションを設定することができます。次に、例を示します:

    $ findbugs -textui -property "cfg.noprune=true" myApp.jar

設定することができる分析オプションの一覧を に示します。

### 設定可能な分析プロパティー

プロパティー名 | 設定値 | 目的
--- | --- | ---
findbugs.assertionmethods | コンマ区切りの完全修飾メソッド名リスト : 例、 "com.foo.MyClass.checkAssertion" | このプロパティーには、プログラムが正しいことをチェックするために使われるメソッドを指定します。これらのメソッドを指定することで、 チェックメソッドで確認した値に対する null 参照アクセスディテクタの誤検出を回避できます。
findbugs.de.comment | true または false | true に設定すると、 DroppedException (無視された例外) ディテクタは空の catch ブロック にコメントが無いか探します。そして、コメントがみつかった場合には警告が報告されません。
findbugs.maskedfields.locals | true または false | true に設定すると、フィールドを隠蔽しているローカル変数に対して優先度(低)の警告が発行されます。デフォルトは、 false です。
findbugs.nullderef.assumensp | true または false | 使用されません。 (意図 : true に設定すると、null 参照アクセスディテクタはメソッドからの戻り値、または、メソッドに受け渡される引数を null であると仮定します。デフォルトは、 false です。このプロパティーを有効にすると、大量の誤検出が生成されるであろうことに注意してください。)
findbugs.refcomp.reportAll | true または false | true に設定すると、 == および != 演算子を使っている疑わしい参照比較がすべて報告されます。 false に設定すると、同様の警告は 1 メソッドにつき 1 つしか発行されません。デフォルトは、 false です。
findbugs.sf.comment | true または false | true に設定すると、 SwitchFallthrough ディテクタはソースコードに「fall」または「nobreak」という単語を含んだコメントを記載していない caseラベル に限り警告を報告します。(この機能が正しく動作するためには、正確なソースパスが必要です。) これにより、意図的ではない switch 文の fallthrough を発見し易くなります。

## アノテーション

&FindBugs; はいくつかのアノテーションをサポートしています。開発者の意図を明確にすることで、 FindBugs はより的確に警告を発行することができます。アノテーションを使用するためには Java 5 が必要であり、 annotations.jar および jsr305.jar ファイルをコンパイル時のクラスパスに含める必要があります。

`edu.umd.cs.findbugs.annotations.CheckForNull`
  `[Target]` Field, Method, Parameter

  アノテーションをつけた要素は、 null である可能性があります。したがって、当該要素を使用する際は null チェックをするべきです。このアノテーションをメソッドに適用すると、メソッドの戻り値に適用されます。

`edu.umd.cs.findbugs.annotations.CheckReturnValue`
  `[Target]` Method, Constructor
  `[Parameter]`

    `priority:` 警告の優先度を指定します (HIGH, MEDIUM, LOW, IGNORE) 。デフォルト値 :MEDIUM。

    `explanation:`戻り値をチェックしなけばならない理由をテキストで説明します。デフォルト値 :""。

  このアノテーションを使用して、呼出し後に戻り値をチェックすべきメソッドを表すことができます。

`edu.umd.cs.findbugs.annotations.DefaultAnnotation`
  `[Target]` Type, Package
  `[Parameter]`

    `value:`アノテーションクラスのclassオブジェクト。複数のクラスを指定することができます。

    `priority:`省略時の優先度を指定します (HIGH, MEDIUM, LOW, IGNORE) 。デフォルト値 :MEDIUM。

  Indicates that all members of the class or package should be annotated with the default value of the supplied annotation classes. This would be used for behavior annotations such as @NonNull, @CheckForNull, or @CheckReturnValue. In particular, you can use @DefaultAnnotation(NonNull.class) on a class or package, and then use @Nullable only on those parameters, methods or fields that you want to allow to be null.

`edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields`
  `[Target]` Type, Package
  `[Parameter]`

    `value:`アノテーションクラスのclassオブジェクト。複数のクラスを指定することができます。

    `priority:`省略時の優先度を指定します (HIGH, MEDIUM, LOW, IGNORE) 。デフォルト値 :MEDIUM。

  This is same as the DefaultAnnotation except it only applys to fields.

`edu.umd.cs.findbugs.annotations.DefaultAnnotationForMethods`
  `[Target]` Type, Package
  `[Parameter]`

    `value:`アノテーションクラスのclassオブジェクト。複数のクラスを指定することができます。

    `priority:`省略時の優先度を指定します (HIGH, MEDIUM, LOW, IGNORE) 。デフォルト値 :MEDIUM。

  This is same as the DefaultAnnotation except it only applys to methods.

`edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters`
  `[Target]` Type, Package
  `[Parameter]`

    `value:`アノテーションクラスのclassオブジェクト。複数のクラスを指定することができます。

    `priority:`省略時の優先度を指定します (HIGH, MEDIUM, LOW, IGNORE) 。デフォルト値 :MEDIUM。

  This is same as the DefaultAnnotation except it only applys to method parameters.

`edu.umd.cs.findbugs.annotations.NonNull`
  `[Target]` Field, Method, Parameter

  アノテーションをつけた要素は、 null であってはいけません。アノテーションをつけたフィールドは、構築完了後 null であってはいけません。アノテーションをつけたメソッドは、 null ではない値を戻り値としなければなりません。

`edu.umd.cs.findbugs.annotations.Nullable`
  `[Target]` Field, Method, Parameter

  アノテーションをつけた要素は、 null であってはいけません。In general, this means developers will have to read the documentation to determine when a null value is acceptable and whether it is neccessary to check for a null value. FindBugs will treat the annotated items as though they had no annotation.

  In pratice this annotation is useful only for overriding an overarching NonNull annotation.

`edu.umd.cs.findbugs.annotations.OverrideMustInvoke`
  `[Target]` Method
  `[Parameter]`

    `value:`Specify when the super invocation should be performed (FIRST, ANYTIME, LAST). Default value:ANYTIME.

  Used to annotate a method that, if overridden, must (or should) be invoke super in the overriding method. Examples of such methods include finalize() and clone(). The argument to the method indicates when the super invocation should occur: at any time, at the beginning of the overriding method, or at the end of the overriding method. (This anotation is not implmemented in FindBugs as of September 8, 2006).

`edu.umd.cs.findbugs.annotations.PossiblyNull`

  This annotation is deprecated. Use CheckForNull instead.

`edu.umd.cs.findbugs.annotations.SuppressWarnings`
  `[Target]` Type, Field, Method, Parameter, Constructor, Package
  `[Parameter]`

    `value:`The name of the warning. More than one name can be specified.

    `justification:`Reason why the warning should be ignored. デフォルト値 :""。

  The set of warnings that are to be suppressed by the compiler in the annotated element. Duplicate names are permitted. The second and successive occurrences of a name are ignored. The presence of unrecognized warning names is not an error: Compilers must ignore any warning names they do not recognize. They are, however, free to emit a warning if an annotation contains an unrecognized warning name. Compiler vendors should document the warning names they support in conjunction with this annotation type. They are encouraged to cooperate to ensure that the same names work across multiple compilers.

`edu.umd.cs.findbugs.annotations.UnknownNullness`
  `[Target]` Field, Method, Parameter

  Used to indicate that the nullness of the target is unknown, or my vary in unknown ways in subclasses.

`edu.umd.cs.findbugs.annotations.UnknownNullness`
  `[Target]` Field, Method, Parameter

  Used to indicate that the nullness of the target is unknown, or my vary in unknown ways in subclasses.

また、 &FindBugs; 次に示すアノテーションもサポートしています。 :

- net.jcip.annotations.GuardedBy
- net.jcip.annotations.Immutable
- net.jcip.annotations.NotThreadSafe
- net.jcip.annotations.ThreadSafe

Java Concurrency in Practice の API ドキュメント を参照してください。

## rejarForAnalysis の使用方法

プロジェクトに多くの jar ファイル があったり、 jar ファイルが多くのディレクトリに点在したりする場合は、 `rejarForAnalysis` スクリプトを使用すると FindBugs の実行が比較的簡単になります。このスクリプトは、数多い jar ファイルを集めて 1 つの大きな jar ファイルに結合します。そうすると、分析時にFindBugs に jar ファイルを設定することが比較的簡単になります。このスクリプトは、 unix システムの 'find' コマンドと組み合わせるととりわけ有用になります ; 次に例を示します。 `find . -name '*.jar' | xargs rejarForAnalysis` .

また、 `rejarForAnalysis` スクリプトは巨大なプロジェクトを複数の jar ファイルに分割することに使用できます。プロジェクトのクラスファイルは、複数の jar ファイルに均等に配分されます。これは、プロジェクト全体に対して FindBugs を実行すると時間とメモリ消費が著しい場合に有用です。プロジェクト全体に対して FindBugs を実行する代わりに、 `rejarForAnalysis` ですべてのクラスを含む大きな jar ファイルを構築します。続いて、 `rejarForAnalysis` を再び実行して複数の jar ファイルに分割します。そして、各々の jar ファイルに対して順に FindBugs を実行します。その際、 `-auxclasspath` に最初に 1 つにまとめた jar ファイルを指定してください。

`rejarForAnalysis` スクリプトに指定することができるオプションを以下に示します :

`-maxAge` 日数

  最後に更新された日からの経過時間を日単位で指定します (指定した日数より古い jar ファイルは無視されます)。

`-inputFileList` ファイル名

  jar ファイル名を記載したテキストファイルを指定します。

`-maxClasses` クラス数

  analysis*.jar ファイル 1 ファイルに対するクラスの最大数を指定します。

`-prefix` プレフィックス

  分析するクラス名のプレフィックスを指定します (例、 edu.umd.cs.) 。

## &FindBugs;™ によるデータ・マイニング

バグデータベースへの高機能の問い合わせ機能、および、調査対象のコードの複数のバージョンにわたる警告の追跡記録機能を、 FindBugs は内蔵しています。これらを使って次のようなことができます。すなわち、いつバグが最初持ち込まれたかを捜し出すこと、最終リリース以後持ち込まれた警告の分析を行うこと、または、無限再起ループの数を時間軸でグラフにすることです。

これらの技術は、 FindBugs が警告の保存に使う XML 書式を使用します。これらの XML ファイルは、通常、特定の 1 分析に対する警告が入れられています。しかしそれらには、一連のソフトウェアのビルドやバージョンに対する分析結果を格納することもできます。

すべての FindBugs XML バグデータベースには、バージョン名とタイム・スタンプ が入れられています。FindBugs は分析が行われるファイルの更新時刻からタイム・スタンプを計算します (例えば、タイム・スタンプはクラスファイルの生成時刻になるようになっています。分析が行われた時刻ではありません) 。各々のバグデータベースには、バージョン名も入れられています。バージョン名とタイム・スタンプは、 `setBugDatabaseInfo` () コマンドを使用して手動で設定することもできます。

複数バージョンを格納するバグデータベースにおいては、分析されるコードの各バージョンごとにシーケンス番号が割り当てられます。これらのシーケンス番号は単に 0 から始まる連続する整数値です (例えば、 4 つのコードバージョンを格納するバグデータベースには、バージョン 0~3 が入れられます) 。バグデータベースにはまた、各バージョンの名前とタイム・スタンプがそれぞれ記録されます。`filterBugs` コマンドを使用すると、シーケンス番号、バージョン名またはタイム・スタンプからバージョンを参照することができます。

1 バージョンを格納するバグデータベースの集合から、 1 個の複数バージョンバグデータベースを作成することができます。また、複数バージョンバグデータベースに対して、それ以後に作成された 1 バージョンのバグデータベースを結合することができます。

これらのコマンドのいくつかは、 ant タスクとして実行することができます。コマンドの実行方法および属性・引数の詳細は、以下を参照してください。以下のすべての例においては、 `findbugs.lib` `refid` が正しく設定されていることを前提としています。設定方法の一例を次に示します :

       <!-- findbugs タスク定義 -->
       <property name="findbugs.home" value="/your/path/to/findbugs" />
       <path id="findbugs.lib">
          <fileset dir="${findbugs.home}/lib">
             <include name="findbugs-ant.jar"/>
          </fileset>
       </path>

### コマンド

FindBugs データ・マイニング ツールはすべてコマンドラインから実行することができます。また、いくつかのより有用なコマンドは、 ant ビルドファイルから実行することができます。

コマンドラインツールについて簡単に説明します :

`unionBugs`

  別のクラスに対する別個の分析結果を結合します。

`computeBugHistory`

  複数バージョンから得られた複数のバグ警告を、マージして 1 個の複数バージョンバグデータベースにします。これを使って、既存の複数バージョンバグデータベースに更にバージョンを追加したり、 1 バージョンを格納するバグデータベースの集合から 1 個の複数バージョンバグデータベースを作成したり、できます。

`setBugDatabaseInfo`

  リビジョン名やタイム・スタンプなどの情報を XML データベースに設定します。

`listBugDatabaseInfo`

  XML データベースにあるリビジョン名やタイム・スタンプなどの情報を一覧表示します。

`filterBugs`

  バグデータベースの部分集合を選択します。

`mineBugHistory`

  複数バージョンバグデータベースの各バージョン毎の警告数を一覧にした表を作成します。

`defectDensity`

  プロジェクト全体およびクラス毎・パッケージ毎の不良密度 (1000 NCSS 毎の警告数) に関する情報を一覧表示します。

`convertXmlToText`

  XML 形式のバグ警告を、 1 行 1 バグのテキスト形式、または、HTML形式に変換します。

#### unionBugs

分析するのにアプリケーションの jar ファイルを分割している場合、このコマンドを使用することで、別個に生成された XML バグ警告ファイルをすべての警告を含んでいる 1 つの ファイルにすることができます。

同じファイルの異なるバージョンを分析した結果を結合する場合は、このコマンドを使用しないでください。代わりに `computeBugHistory` を使用してください。

XML ファイルは、コマンドラインで指定してください。結果は、標準出力に送られます。

#### computeBugHistory

このコマンドを使用することで、分析するソフトウェアの異なるビルドまたはバージョンの情報を含むバグデータベースを生成することができます入力として提供したファイルの 1 番目のファイルから履歴が取得されます。後に続くファイルは 1 バージョンのバグデータベースであるようにしてください (もし、履歴を持っていたとしても無視されます) 。

デフォルトでは、結果は標準出力に送られます。

この機能は、 ant からも使用することができます。まず次に示すように、ビルドファイルに `computeBugHistory` を taskdef で定義します :

    <taskdef name="computeBugHistory" classname="edu.umd.cs.findbugs.anttask.ComputeBugHistoryTask">
        <classpath refid="findbugs.lib" />
    </taskdef>

この ant タスクに指定できる属性を、下表に一覧で示します。入力ファイルを指定するには、 `<datafile>` 要素を入れ子にして入れてください。次に、例を示します:

    <computeBugHistory home="${findbugs.home}" ...>
        <datafile name="analyze1.xml"/>
        <datafile name="analyze2.xml"/>
    </computeBugHistory>

##### computeBugHistory コマンドのオプション一覧

コマンドラインオプション | Ant 属性 | 目的
--- | --- | ---
-output <file> | output="<file>" | 出力結果を保存するファイル名を指定します。 (同時に入力ファイルにもなりえます)
-overrideRevisionNames[:truth] | overrideRevisionNames="[true|false]" | ファイル名から算出されるそれぞれのバージョン名を指定変更します。
-noPackageMoves[:truth] | noPackageMoves="[true|false]" | パッケージを移動したクラスがある場合、当該クラスの警告は別の存在として扱われます。
-preciseMatch[:truth] | preciseMatch="[true|false]" | バグパターンが正確に一致することを要求します。
-precisePriorityMatch[:truth] | precisePriorityMatch="[true|false]" | 優先度が正確に一致した場合のみ警告が同一であると判断されます。
-quiet[:truth] | quiet="[true|false]" | エラーが発生しない限り、標準出力には何も表示されません。
-withMessages[:truth] | withMessages="[true|false]" | 出力 XML に人間が読むことができるバグメッセージが含まれます。

#### filterBugs

このコマンドを使用することで、 FindBugs XML 警告ファイルから一部分を選び出して新規 FindBugs 警告ファイルに選択された部分を書き込むことができます。

このコマンドには、オプション群に続いて 0 個から 2 個の findbugs xml バグファイルを指定することができます。

ファイル名をひとつも指定しない場合は、標準入力から読んで標準出力に出力されます。ファイル名を 1 個 指定した場合は、指定したファイルから読んで標準出力に出力されます。ファイル名を 2 個 指定した場合は、 1 番目に指定したファイルから読んで 2 番目に指定したファイルに出力されます。

この機能は、 ant からも使用することができます。まず次に示すように、ビルドファイルに `filterBugs` を taskdef で定義します :

    <taskdef name="filterBugs" classname="edu.umd.cs.findbugs.anttask.FilterBugsTask">
        <classpath refid="findbugs.lib" />
    </taskdef>

この ant タスクに指定できる属性を、下表に一覧で示します。入力ファイルを指定するには、 `input` 属性を使用するか、 `<datafile>` 要素を入れ子にして入れてください。次に、例を示します:

    <filterBugs home="${findbugs.home}" ...>
        <datafile name="analyze.xml"/>
    </filterBugs>

##### filterBugs コマンドのオプション一覧

コマンドラインオプション | Ant 属性 | 目的
--- | --- | ---
| input="<file>" | 入力ファイルを指定します。
| output="<file>" | 出力ファイルを指定します。
-not | not="[true|false]" | フィルターのスイッチを反転します。
-withSource[:truth] | withSource="[true|false]" | ソースが入手可能な警告のみ出力されます。
-exclude <filter file> | exclude="<filter file>" | フィルターに一致するバグが除外されます。
-include <filter file> | include="<filter file>" | フィルターに一致するバグのみを含まれます。
-annotation <text> | annotation="<text>" | 手で入力した注釈に指定した文言を含む警告のみ出力されます。
-after <when> | after="<when>" | 指定したバージョンより後に初めて出現した警告のみ出力されます。
-before <when> | before="<when>" | 指定したバージョンより前に初めて出現した警告のみ出力されます。
-first <when> | first="<when>" | 指定したバージョンに初めて出現した警告のみ出力されます。
-last <when> | last="<when>" | 指定したバージョンが出現した最後である警告のみ出力されます。
-fixed <when> | fixed="<when>" | 指定したバージョンの前回のバージョンが出現した最後である警告のみ出力されます。 (`-last` に優先します)。
-present <when> | present="<when>" | 指定したバージョンに存在する警告のみ出力されます。
-absent <when> | absent="<when>" | 指定したバージョンに存在しない警告のみ出力されます。
-active[:truth] | active="[true|false]" | 最終通番に存在する警告のみ出力されます。
-introducedByChange[:truth] | introducedByChange="[true|false]" | 存在するクラスの変更によってもたらされた警告のみ出力されます。
-removedByChange[:truth] | removedByChange="[true|false]" | 存在するクラスの変更によって除去された警告のみ出力されます。
-newCode[:truth] | newCode="[true|false]" | 新クラスの追加によってもたらされた警告のみ出力されます。
-removedCode[:truth] | removedCode="[true|false]" | クラスの削除によって除去された警告のみ出力されます。
-priority <level> | priority="<level>" | 指定した優先度以上の優先度をもつ警告のみ出力されます。
-class <pattern> | class="<class>" | 指定したパターンに一致する主クラスをもつ警告のみ出力されます。
-bugPattern <pattern> | bugPattern="<pattern>" | 指定したパターンに一致するバグ種別をもつ警告のみ出力されます。
-category <category> | category="<category>" | 指定した文字列で始まるカテゴリーの警告のみ出力されます。
-designation <designation> | designation="<designation>" | 指定したバグ分類指定をもつ警告のみ出力されます。 (例、 -designation SHOULD_FIX)
-withMessages[:truth] | withMessages="[true|false]" | テキストメッセージを含んだ XML が生成されます。

#### mineBugHistory

このコマンドを使用することで、複数バージョンバグデータベースの各バージョン毎の警告数を一覧にした表を作成することができます。

この機能は、 ant からも使用することができます。まず次に示すように、ビルドファイルに `mineBugHistory` を taskdef で定義します :

    <taskdef name="mineBugHistory" classname="edu.umd.cs.findbugs.anttask.MineBugHistoryTask">
        <classpath refid="findbugs.lib" />
    </taskdef>

この ant タスクに指定できる属性を、下表に一覧で示します。入力ファイルを指定するには、 `input` 属性を使用するか、 `<datafile>` 要素を入れ子にして入れてください。次に、例を示します:

    <mineBugHistory home="${findbugs.home}" ...>
        <datafile name="analyze.xml"/>
    </mineBugHistory>

##### mineBugHistory コマンドのオプション一覧

コマンドラインオプション | Ant 属性 | 目的
--- | --- | ---
| input="<file>" | 入力ファイルを指定します。
| output="<file>" | 出力ファイルを指定します。
-formatDates | formatDates="[true|false]" | データがテキスト形式で描画されます。
-noTabs | noTabs="[true|false]" | タブの代わりに複数スペースでカラムが区切られます (下記参照)。
-summary | summary="[true|false]" | 最新 10 件の変更の要約が出力されます。

`-noTabs` 出力を使うことで、固定幅フォントのシェルで読み易くなります。数値カラムは右寄せされるので、スペースがカラム値の前に挿入されます。また、このオプションを使用した場合、 `-formatDates` を指定したときに要約の日付を描画するのに空白が埋め込まれなくなります。

出力される表は、 (`-noTabs` が無ければ) タブ区切りで次に示すカラムから成ります :

##### mineBugHistory 出力のカラム一覧

表題 | 目的
--- | ---
seq | シーケンス番号 (0 始まりの連続した整数値)
version | バージョン名
time | リリースされた日時
classes | 分析されたクラス数
NCSS | コメント文を除いた命令数 (Non Commenting Source Statements)
added | 前回のバージョンに存在したクラスにおける新規警告数
newCode | 前回のバージョンに存在しなかったクラスにおける新規警告数
fixed | 現在のバージョンに存在するクラスにおける除去された警告数
removed | 現在のバージョンに存在しないクラスの前回のバージョンにおける警告数
retained | 現在のバージョンと前回のバージョンの両方に存在する警告の数
dead | 以前のバージョンに存在したが現在のバージョンにも直前のバージョンにも存在しない警告の数
active | 現在のバージョンに存在する警告総数

#### defectDensity

このコマンドを使用することで、プロジェクト全体およびクラス毎・パッケージ毎の不良密度 (1000 NCSS 毎の警告数) に関する情報を一覧表示できます。標準入力から読み込む場合はファイル指定なしで、そうでなければ、コマンドラインでファイルを指定して、このコマンドを実行します。

出力される表は、次に示すカラムから成ります。また、プロジェクト全体情報の行、および、4 個以上の警告を含んでいる各パッケージ情報または各クラス情報の行も出力されます。

##### defectDensity 出力のカラム一覧

表題 | 目的
--- | ---
kind | プロジェクト (project)、パッケージ (package) またはクラス (class)
name | プロジェクト、パッケージまたはクラスの名前
density | 1000 NCSS 毎の警告数
bugs | 警告数
NCSS | コメント文を除いた命令数 (Non Commenting Source Statements)

#### convertXmlToText

このコマンドを使用することで、XML 形式のバグ警告を、 1 行 1 バグのテキスト形式、または、HTML形式に変換することができます。

この機能は、 ant からも使用することができます。まず次に示すように、ビルドファイルに `convertXmlToText` を taskdef で定義します :

    <taskdef name="convertXmlToText" classname="edu.umd.cs.findbugs.anttask.ConvertXmlToTextTask">
        <classpath refid="findbugs.lib" />
    </taskdef>

この ant タスクに指定できる属性を、下表に一覧で示します。

##### convertXmlToText コマンドのオプション一覧

コマンドラインオプション | Ant 属性 | 目的
--- | --- | ---
| input="<filename>" | 入力ファイルを指定します。
| output="<filename>" | 出力ファイルを指定します。
-longBugCodes | longBugCodes="[true|false]" | 2 文字のバグ略称の代わりに、省略なしのバグパターンコードを使用します。
| format="text" | プレーンテキストの出力が作成されます。1 行につき 1 つのバグが出力されます。コマンドライン時のデフォルトです。
-html[:stylesheet] | format="html:<stylesheet>" | 指定されたスタイルシートを使用して出力が作成されます (下記参照) 。省略した場合は、 default.xsl が使用されます。

-html/format オプションには、plain.xsl 、 default.xsl 、 fancy.xsl 、 fancy-hist.xsl または ユーザ自身が作成した XSL スタイルシートのいずれかを指定することができます。オプション名をよそに、 html 以外の形式を出力するスタイルシートを指定することもできます。FindBugs に含まれているスタイルシート(上述)以外のスタイルシートを使用する場合は、オプション -html/format で当該スタイルシートへのパスまたは URL を指定してください。

#### setBugDatabaseInfo

このコマンドを使用することで、指定したバグ警告にメタ情報を設定することができます。このコマンドには次に示すオプションがあります:

この機能は、 ant からも使用することができます。まず次に示すように、ビルドファイルに `setBugDatabaseInfo` を taskdef で定義します :

    <taskdef name="setBugDatabaseInfo" classname="edu.umd.cs.findbugs.anttask.SetBugDatabaseInfoTask">
        <classpath refid="findbugs.lib" />
    </taskdef>

この ant タスクに指定できる属性を、下表に一覧で示します。入力ファイルを指定するには、 `input` 属性を使用するか、 `<datafile>` 要素を入れ子にして入れてください。次に、例を示します:

    <setBugDatabaseInfo home="${findbugs.home}" ...>
        <datafile name="analyze.xml"/>
    </setBugDatabaseInfo>

##### setBugDatabaseInfo オプション一覧

コマンドラインオプション | Ant 属性 | 目的
--- | --- | ---
| input="<file>" | 入力ファイルを指定します。
| output="<file>" | 出力ファイルを指定します。
-name <name> | name="<name>" | 最新リビジョンの名前を設定します。
-timestamp <when> | timestamp="<when>" | 最新リビジョンのタイム・スタンプを設定します。
-source <directory> | source="<directory>" | ソースを検索するディレクトリーを追加指定します。
-findSource <directory> | findSource="<directory>" | 指定したディレクトリー内を検索して関連するソースの場所を追加します。
-suppress <filter file> | suppress="<filter file>" | 指定したファイルに一致する警告を抑止します (以前に指定した抑止設定は置き換えられます)。
-withMessages | withMessages="[true|false]" | XMLにテキストメッセージを追加します。
-resetSource | resetSource="[true|false]" | ソース検索パスをすべて削除します。

#### listBugDatabaseInfo

このコマンドの実行においては、コマンドラインで 0 個以上の xml バグデータベースファイル名を指定します。ファイル名を1つも指定しなければ、標準出力から読み込みを行いテーブルのヘッダーは生成されません。

このコマンドには 1 つだけオプションがあります : `-formatDates` を指定するとテキスト形式でデータが描画されます。

出力される表は、各バグデータベースごとに行を持ち、次に示すカラムから成ります :

##### listBugDatabaseInfo カラム一覧

カラム | 目的
--- | ---
version | バージョン名
time | リリースされた日時
classes | 分析されたクラス数
NCSS | コメント文を除いた命令数 (Non Commenting Source Statements)
total | 全警告数
high | 優先度(高)の警告の総数
medium | 優先度(中)の警告の総数
low | 優先度(低)の警告の総数
filename | データベースのファイル名

### 例

#### 提供されたシェル・スクリプトを使用しての履歴マイニング

以下はすべて、 jdk1.6.0-b12, jdk1.6.0-b13, ..., jdk1.6.0-b60 のディレクトリに対してコマンドを実行しています。

以下のコマンドを実行してみます :

    computeBugHistory jdk1.6.0-b* | filterBugs -bugPattern IL_ | mineBugHistory -formatDates

すると、次のような出力が行われます :

    seq	version	time	classes	NCSS	added	newCode	fixed	removed	retained	dead	active
    0	jdk1.6.0-b12	"Thu Nov 11 09:07:20 EST 2004"	13128	811569	0	4	0	0	0	0	4
    1	jdk1.6.0-b13	"Thu Nov 18 06:02:06 EST 2004"	13128	811570	0	0	0	0	4	0	4
    2	jdk1.6.0-b14	"Thu Dec 02 06:12:26 EST 2004"	13145	811786	0	0	2	0	2	0	2
    3	jdk1.6.0-b15	"Thu Dec 09 06:07:04 EST 2004"	13174	811693	0	0	1	0	1	2	1
    4	jdk1.6.0-b16	"Thu Dec 16 06:21:28 EST 2004"	13175	811715	0	0	0	0	1	3	1
    5	jdk1.6.0-b17	"Thu Dec 23 06:27:22 EST 2004"	13176	811974	0	0	0	0	1	3	1
    6	jdk1.6.0-b19	"Thu Jan 13 06:41:16 EST 2005"	13176	812011	0	0	0	0	1	3	1
    7	jdk1.6.0-b21	"Thu Jan 27 05:57:52 EST 2005"	13177	812173	0	0	0	0	1	3	1
    8	jdk1.6.0-b23	"Thu Feb 10 05:44:36 EST 2005"	13179	812188	0	0	0	0	1	3	1
    9	jdk1.6.0-b26	"Thu Mar 03 06:04:02 EST 2005"	13199	811770	0	0	0	0	1	3	1
    10	jdk1.6.0-b27	"Thu Mar 10 04:48:38 EST 2005"	13189	812440	0	0	0	0	1	3	1
    11	jdk1.6.0-b28	"Thu Mar 17 02:54:22 EST 2005"	13185	812056	0	0	0	0	1	3	1
    12	jdk1.6.0-b29	"Thu Mar 24 03:09:20 EST 2005"	13117	809468	0	0	0	0	1	3	1
    13	jdk1.6.0-b30	"Thu Mar 31 02:53:32 EST 2005"	13118	809501	0	0	0	0	1	3	1
    14	jdk1.6.0-b31	"Thu Apr 07 03:00:14 EDT 2005"	13117	809572	0	0	0	0	1	3	1
    15	jdk1.6.0-b32	"Thu Apr 14 02:56:56 EDT 2005"	13169	811096	0	0	0	0	1	3	1
    16	jdk1.6.0-b33	"Thu Apr 21 02:46:22 EDT 2005"	13187	811942	0	0	0	0	1	3	1
    17	jdk1.6.0-b34	"Thu Apr 28 02:49:00 EDT 2005"	13195	813488	0	1	0	0	1	3	2
    18	jdk1.6.0-b35	"Thu May 05 02:49:04 EDT 2005"	13457	829837	0	0	0	0	2	3	2
    19	jdk1.6.0-b36	"Thu May 12 02:59:46 EDT 2005"	13462	831278	0	0	0	0	2	3	2
    20	jdk1.6.0-b37	"Thu May 19 02:55:08 EDT 2005"	13464	831971	0	0	0	0	2	3	2
    21	jdk1.6.0-b38	"Thu May 26 03:08:16 EDT 2005"	13564	836565	0	0	0	0	2	3	2
    22	jdk1.6.0-b39	"Fri Jun 03 03:10:48 EDT 2005"	13856	849992	0	1	0	0	2	3	3
    23	jdk1.6.0-b40	"Thu Jun 09 03:30:28 EDT 2005"	15972	959619	0	2	0	0	3	3	5
    24	jdk1.6.0-b41	"Thu Jun 16 03:19:22 EDT 2005"	15972	959619	0	0	0	0	5	3	5
    25	jdk1.6.0-b42	"Fri Jun 24 03:38:54 EDT 2005"	15966	958581	0	0	0	0	5	3	5
    26	jdk1.6.0-b43	"Thu Jul 14 03:09:34 EDT 2005"	16041	960544	0	0	0	0	5	3	5
    27	jdk1.6.0-b44	"Thu Jul 21 03:05:54 EDT 2005"	16041	960547	0	0	0	0	5	3	5
    28	jdk1.6.0-b45	"Thu Jul 28 03:26:10 EDT 2005"	16037	960606	0	0	1	0	4	3	4
    29	jdk1.6.0-b46	"Thu Aug 04 03:02:48 EDT 2005"	15936	951355	0	0	0	0	4	4	4
    30	jdk1.6.0-b47	"Thu Aug 11 03:18:56 EDT 2005"	15964	952387	0	0	1	0	3	4	3
    31	jdk1.6.0-b48	"Thu Aug 18 08:10:40 EDT 2005"	15970	953421	0	0	0	0	3	5	3
    32	jdk1.6.0-b49	"Thu Aug 25 03:24:38 EDT 2005"	16048	958940	0	0	0	0	3	5	3
    33	jdk1.6.0-b50	"Thu Sep 01 01:52:40 EDT 2005"	16287	974937	1	0	0	0	3	5	4
    34	jdk1.6.0-b51	"Thu Sep 08 01:55:36 EDT 2005"	16362	979377	0	0	0	0	4	5	4
    35	jdk1.6.0-b52	"Thu Sep 15 02:04:08 EDT 2005"	16477	979399	0	0	0	0	4	5	4
    36	jdk1.6.0-b53	"Thu Sep 22 02:00:28 EDT 2005"	16019	957900	0	0	1	0	3	5	3
    37	jdk1.6.0-b54	"Thu Sep 29 01:54:34 EDT 2005"	16019	957900	0	0	0	0	3	6	3
    38	jdk1.6.0-b55	"Thu Oct 06 01:54:14 EDT 2005"	16051	959014	0	0	0	0	3	6	3
    39	jdk1.6.0-b56	"Thu Oct 13 01:54:12 EDT 2005"	16211	970835	0	0	0	0	3	6	3
    40	jdk1.6.0-b57	"Thu Oct 20 01:55:26 EDT 2005"	16279	971627	0	0	0	0	3	6	3
    41	jdk1.6.0-b58	"Thu Oct 27 01:56:30 EDT 2005"	16283	971945	0	0	0	0	3	6	3
    42	jdk1.6.0-b59	"Thu Nov 03 01:56:58 EST 2005"	16232	972193	0	0	0	0	3	6	3
    43	jdk1.6.0-b60	"Thu Nov 10 01:54:18 EST 2005"	16235	972346	0	0	0	0	3	6	3

次に示すコマンドを実行すると、db.xml 中間ファイルを生成することなく直接同じ情報を作成できます。

    computeBugHistory  jdk1.6.0-b*/jre/lib/rt.xml | filterBugs -bugPattern IL_ db.xml | mineBugHistory -formatDates

この情報を使って、 Sun JDK1.6.0 の各ビルドにおいて FindBugs によって発見された無限再起ループの数を表すグラフを表示します。青色の領域は、当該ビルドにおける無限再起ループの数を表しています。その上に描かれている赤色の領域は、以前のバージョンには存在したが当該バージョンでは除去された無限再起ループの数を表しています。 (したがって、赤色の領域と青色の領域を足し合わせた高さは決して減少しないことが保証されています。そして、新たに無限再起ループのバグが持ち込まれた時点で増加します) 。赤色の領域の高さは、当該バージョンにおいて修正または削除されたバグ数の合計で算出されます。バージョン 13 および 14 において見られる減少は、 FindBugs を使用して見つかった JDK のバグの報告を Sun が受け取ったことによるものです。

db.xml ファイルは、 jdk1.6.0 のすべてのビルドに対する検索結果を保持しています。したがって、次に示すコマンドを実行することで、優先度(高)または優先度(低)の正確性に関する警告の履歴が表示されます :

    filterBugs -priority M -category C db.xml | mineBugHistory -formatDates

作成される表の例 :

    seq	version	time	classes	NCSS	added	newCode	fixed	removed	retained	dead	active
    0	jdk1.6.0-b12	"Thu Nov 11 09:07:20 EST 2004"	13128	811569	0	1075	0	0	0	0	1075
    1	jdk1.6.0-b13	"Thu Nov 18 06:02:06 EST 2004"	13128	811570	0	0	0	0	1075	0	1075
    2	jdk1.6.0-b14	"Thu Dec 02 06:12:26 EST 2004"	13145	811786	3	0	6	0	1069	0	1072
    3	jdk1.6.0-b15	"Thu Dec 09 06:07:04 EST 2004"	13174	811693	2	1	3	0	1069	6	1072
    4	jdk1.6.0-b16	"Thu Dec 16 06:21:28 EST 2004"	13175	811715	0	0	1	0	1071	9	1071
    5	jdk1.6.0-b17	"Thu Dec 23 06:27:22 EST 2004"	13176	811974	0	0	1	0	1070	10	1070
    6	jdk1.6.0-b19	"Thu Jan 13 06:41:16 EST 2005"	13176	812011	0	0	0	0	1070	11	1070
    7	jdk1.6.0-b21	"Thu Jan 27 05:57:52 EST 2005"	13177	812173	0	0	1	0	1069	11	1069
    8	jdk1.6.0-b23	"Thu Feb 10 05:44:36 EST 2005"	13179	812188	0	0	0	0	1069	12	1069
    9	jdk1.6.0-b26	"Thu Mar 03 06:04:02 EST 2005"	13199	811770	0	0	2	1	1066	12	1066
    10	jdk1.6.0-b27	"Thu Mar 10 04:48:38 EST 2005"	13189	812440	1	0	1	1	1064	15	1065
    11	jdk1.6.0-b28	"Thu Mar 17 02:54:22 EST 2005"	13185	812056	0	0	0	0	1065	17	1065
    12	jdk1.6.0-b29	"Thu Mar 24 03:09:20 EST 2005"	13117	809468	3	0	8	26	1031	17	1034
    13	jdk1.6.0-b30	"Thu Mar 31 02:53:32 EST 2005"	13118	809501	0	0	0	0	1034	51	1034
    14	jdk1.6.0-b31	"Thu Apr 07 03:00:14 EDT 2005"	13117	809572	0	0	0	0	1034	51	1034
    15	jdk1.6.0-b32	"Thu Apr 14 02:56:56 EDT 2005"	13169	811096	1	1	0	1	1033	51	1035
    16	jdk1.6.0-b33	"Thu Apr 21 02:46:22 EDT 2005"	13187	811942	3	0	2	1	1032	52	1035
    17	jdk1.6.0-b34	"Thu Apr 28 02:49:00 EDT 2005"	13195	813488	0	1	0	0	1035	55	1036
    18	jdk1.6.0-b35	"Thu May 05 02:49:04 EDT 2005"	13457	829837	0	36	2	0	1034	55	1070
    19	jdk1.6.0-b36	"Thu May 12 02:59:46 EDT 2005"	13462	831278	0	0	0	0	1070	57	1070
    20	jdk1.6.0-b37	"Thu May 19 02:55:08 EDT 2005"	13464	831971	0	1	1	0	1069	57	1070
    21	jdk1.6.0-b38	"Thu May 26 03:08:16 EDT 2005"	13564	836565	1	7	2	6	1062	58	1070
    22	jdk1.6.0-b39	"Fri Jun 03 03:10:48 EDT 2005"	13856	849992	6	39	5	0	1065	66	1110
    23	jdk1.6.0-b40	"Thu Jun 09 03:30:28 EDT 2005"	15972	959619	7	147	11	0	1099	71	1253
    24	jdk1.6.0-b41	"Thu Jun 16 03:19:22 EDT 2005"	15972	959619	0	0	0	0	1253	82	1253
    25	jdk1.6.0-b42	"Fri Jun 24 03:38:54 EDT 2005"	15966	958581	3	0	1	2	1250	82	1253
    26	jdk1.6.0-b43	"Thu Jul 14 03:09:34 EDT 2005"	16041	960544	5	11	15	8	1230	85	1246
    27	jdk1.6.0-b44	"Thu Jul 21 03:05:54 EDT 2005"	16041	960547	0	0	0	0	1246	108	1246
    28	jdk1.6.0-b45	"Thu Jul 28 03:26:10 EDT 2005"	16037	960606	19	0	2	0	1244	108	1263
    29	jdk1.6.0-b46	"Thu Aug 04 03:02:48 EDT 2005"	15936	951355	13	1	1	32	1230	110	1244
    30	jdk1.6.0-b47	"Thu Aug 11 03:18:56 EDT 2005"	15964	952387	163	8	7	20	1217	143	1388
    31	jdk1.6.0-b48	"Thu Aug 18 08:10:40 EDT 2005"	15970	953421	0	0	0	0	1388	170	1388
    32	jdk1.6.0-b49	"Thu Aug 25 03:24:38 EDT 2005"	16048	958940	1	11	1	0	1387	170	1399
    33	jdk1.6.0-b50	"Thu Sep 01 01:52:40 EDT 2005"	16287	974937	19	27	16	7	1376	171	1422
    34	jdk1.6.0-b51	"Thu Sep 08 01:55:36 EDT 2005"	16362	979377	1	15	3	0	1419	194	1435
    35	jdk1.6.0-b52	"Thu Sep 15 02:04:08 EDT 2005"	16477	979399	0	0	1	1	1433	197	1433
    36	jdk1.6.0-b53	"Thu Sep 22 02:00:28 EDT 2005"	16019	957900	13	12	16	20	1397	199	1422
    37	jdk1.6.0-b54	"Thu Sep 29 01:54:34 EDT 2005"	16019	957900	0	0	0	0	1422	235	1422
    38	jdk1.6.0-b55	"Thu Oct 06 01:54:14 EDT 2005"	16051	959014	1	4	7	0	1415	235	1420
    39	jdk1.6.0-b56	"Thu Oct 13 01:54:12 EDT 2005"	16211	970835	6	8	37	0	1383	242	1397
    40	jdk1.6.0-b57	"Thu Oct 20 01:55:26 EDT 2005"	16279	971627	0	0	0	0	1397	279	1397
    41	jdk1.6.0-b58	"Thu Oct 27 01:56:30 EDT 2005"	16283	971945	0	1	1	0	1396	279	1397
    42	jdk1.6.0-b59	"Thu Nov 03 01:56:58 EST 2005"	16232	972193	6	0	5	0	1392	280	1398
    43	jdk1.6.0-b60	"Thu Nov 10 01:54:18 EST 2005"	16235	972346	0	0	0	0	1398	285	1398
    44	jdk1.6.0-b61	"Thu Nov 17 01:58:42 EST 2005"	16202	971134	2	0	4	0	1394	285	1396

#### 増分履歴メンテナンス

仮に、 db.xml がビルド b12 - b60 に対する findbugs 実行結果を保持している場合、次に示すコマンドを実行することで、 db.xml に b61 に対する実行結果を追加することができます :

    computeBugHistory -output db.xml db.xml jdk1.6.0-b61/jre/lib/rt.xml

### Ant の例

findbugs の実行とその後のデータ・マイニングツールの活用の両方を実行している ant スクリプトの完全な例を以下に示します :

    <project name="analyze_asm_util" default="findbugs">
       <!-- findbugs タスク定義 -->
       <property name="findbugs.home" value="/Users/ben/Documents/workspace/findbugs/findbugs" />
       <property name="jvmargs" value="-server -Xss1m -Xmx800m -Duser.language=en -Duser.region=EN -Dfindbugs.home=${findbugs.home}" />

    	<path id="findbugs.lib">
          <fileset dir="${findbugs.home}/lib">
             <include name="findbugs-ant.jar"/>
          </fileset>
       </path>

       <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
          <classpath refid="findbugs.lib" />
       </taskdef>

       <taskdef name="computeBugHistory" classname="edu.umd.cs.findbugs.anttask.ComputeBugHistoryTask">
          <classpath refid="findbugs.lib" />
       </taskdef>

       <taskdef name="setBugDatabaseInfo" classname="edu.umd.cs.findbugs.anttask.SetBugDatabaseInfoTask">
          <classpath refid="findbugs.lib" />
       </taskdef>

       <taskdef name="mineBugHistory" classname="edu.umd.cs.findbugs.anttask.MineBugHistoryTask">
          <classpath refid="findbugs.lib" />
       </taskdef>

       <!-- findbugs タスク定義 -->
       <target name="findbugs">
          <antcall target="analyze" />
          <antcall target="mine" />
       </target>

       <!-- 分析を行うタスク-->
       <target name="analyze">
          <!-- asm-util に対して findbugs を実行する -->
          <findbugs home="${findbugs.home}"
                    output="xml:withMessages"
                    timeout="90000000"
                    reportLevel="experimental"
                    workHard="true"
                    effort="max"
                    adjustExperimental="true"
                    jvmargs="${jvmargs}"
                    failOnError="true"
                    outputFile="out.xml"
                    projectName="Findbugs"
                    debug="false">
             <class location="asm-util-3.0.jar" />
          </findbugs>
       </target>

       <target name="mine">

          <!-- 最新の分析結果に情報を設定する -->
          <setBugDatabaseInfo home="${findbugs.home}"
          	                  withMessages="true"
          	                  name="asm-util-3.0.jar"
          	                  input="out.xml"
          	                  output="out-rel.xml"/>

          <!-- 履歴ファイル (out-hist.xml) が既に存在するかどうかを確認する -->
          <condition property="mining.historyfile.available">
             <available file="out-hist.xml"/>
          </condition>
          <condition property="mining.historyfile.notavailable">
             <not>
                <available file="out-hist.xml"/>
             </not>
          </condition>

          <!-- このターゲットは、履歴ファイルが存在しないとき (初回) だけ実行されます -->
          <antcall target="history-init">
            <param name="data.file" value="out-rel.xml" />
            <param name="hist.file" value="out-hist.xml" />
          </antcall>
          <!-- 上記以外の場合に実行されます -->
          <antcall target="history">
            <param name="data.file"         value="out-rel.xml" />
            <param name="hist.file"         value="out-hist.xml" />
            <param name="hist.summary.file" value="out-hist.txt" />
          </antcall>
       </target>

       <!-- 履歴ファイルを初期化します -->
       <target name="history-init" if="mining.historyfile.notavailable">
          <copy file="${data.file}" tofile="${hist.file}" />
       </target>

       <!-- バグ履歴を算出します -->
       <target name="history" if="mining.historyfile.available">
          <!-- ${data.file} を ${hist.file} にマージします -->
          <computeBugHistory home="${findbugs.home}"
          	                 withMessages="true"
          	                 output="${hist.file}">
          	  <dataFile name="${hist.file}"/>
          	  <dataFile name="${data.file}"/>
          </computeBugHistory>

          <!-- 履歴を算出して ${hist.summary.file} に出力します -->
          <mineBugHistory home="${findbugs.home}"
          	              formatDates="true"
                          noTabs="true"
          	              input="${hist.file}"
          	              output="${hist.summary.file}"/>
       </target>

    </project>

## ライセンス

名称「FindBugs」および FindBugs のロゴは、メリーランド大学の登録商標です。FindBugs はフリーソフトウェアであり、 Lesser GNU Public License の条件で配布されています。使用承諾書を入手したい場合は、 &FindBugs; 配布物に含まれる `LICENSE.txt` ファイルを参照してください。

最新バージョンの FindBugs および そのソースコードは FindBugs web ページ で入手できます。

## 謝辞

### 貢献者

&FindBugs; was originally written by Bill Pugh (pugh@cs.umd.edu). David Hovemeyer (daveho@cs.umd.edu) implemented some of the detectors, added the Swing GUI, and is a co-maintainer.

Mike Fagan (mfagan@tde.com) contributed the &Ant; build script, the &Ant; task, and several enhancements and bug fixes to the GUI.

Germano Leichsenring contributed Japanese translations of the bug summaries.

David Li contributed the Emacs bug report format.

Peter D. Stout contributed recursive detection of Class-Path attributes in analyzed Jar files, German translations of text used in the Swing GUI, and other fixes.

Peter Friese wrote the &FindBugs; Eclipse plugin.

Rohan Lloyd contributed several Mac OS X enhancements, bug detector improvements, and maintains the Fink package for &FindBugs;.

Hiroshi Okugawa translated the &FindBugs; manual and more of the bug summaries into Japanese.

Phil Crosby enhanced the Eclipse plugin to add a view to display the bug details.

Dave Brosius fixed a number of bugs, added user preferences to the Swing GUI, improved several bug detectors, and contributed the string concatenation detector.

Thomas Klaeger contributed a number of bug fixes and bug detector improvements.

Andrei Loskutov made a number of improvements to the Eclipse plugin.

Brian Goetz contributed a major refactoring of the visitor classes to improve readability and understandability.

Pete Angstadt fixed several problems in the Swing GUI.

Francis Lalonde provided a task resource file for the FindBugs Ant task.

Garvin LeClaire contributed support for output in Xdocs format, for use by Maven.

Holger Stenzhorn contributed improved German translations of items in the Swing GUI.

Juha Knuutila contributed Finnish translations of items in the Swing GUI.

Tanel Lebedev contributed Estonian translations of items in the Swing GUI.

Hanai Shisei (ruimo) contributed full Japanese translations of bug messages, and text used in the Swing GUI.

David Cotton contributed Fresh translations for bug messages and for the Swing GUI.

Michael Tamm contributed support for the "errorProperty" attribute in the Ant task.

Thomas Kuehne improved the German translation of the Swing GUI.

Len Trigg improved source file support for the Emacs output mode.

Greg Bentz provided a fix for the hashcode/equals detector.

K. Hashimoto contributed internationalization fixes and several other bug fixes.

Glenn Boysko contributed support for ignoring specified local variables in the dead local store detector.

Jay Dunning contributed a detector to find equality comparisons of floating-point values, and overhauled the analysis summary report and its representation in the saved XML format.

Olivier Parent contributed updated French translations for bug descriptions and Swing GUI.

Chris Nappin contributed the `plain.xsl` stylesheet.

Etienne Giraudy contributed the `fancy.xsl` and `fancy-hist.xsl` stylesheets, and made improvements to the `-xml:withMessages` option.

Takashi Okamoto fixed bugs in the project preferences dialog in the Eclipse plugin, and contributed to its internationalization and localization.

Thomas Einwaller fixed bugs in the project preferences dialog in the Eclipse plugin.

Jeff Knox contributed support for the warningsProperty attribute in the Ant task.

Peter Hendriks extended the Eclipse plugin preferences, and fixed a bug related to renaming the Eclipse plugin ID.

Mark McKay contributed an Ant task to launch the findbugs frame.

Dieter von Holten (dvholten) contributed some German improvements to findbugs_de.properties.

If you have contributed to &FindBugs;, but aren't mentioned above, please send email to findbugs@cs.umd.edu (and also accept our humble apologies).

### 使用しているソフトウェア

&FindBugs; は、いくつかのオープンソースソフトウェアパッケージを使用しています。これらがなければ、 &FindBugs; の開発は、より一層困難なものになったことでしょう。

#### BCEL

&FindBugs; includes software developed by the Apache Software Foundation (http://www.apache.org/). Specifically, it uses the Byte Code Engineering Library.

#### ASM

&FindBugs; uses the ASM bytecode framework, which is distributed under the following license:

> Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved.

> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

> 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

> 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

> 3. Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#### DOM4J

&FindBugs; uses DOM4J, which is distributed under the following license:

> Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.

> Redistribution and use of this software and associated documentation ("Software"), with or without modification, are permitted provided that the following conditions are met:

> 1. Redistributions of source code must retain copyright statements and notices. Redistributions must also contain a copy of this document.

> 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

> 3. The name "DOM4J" must not be used to endorse or promote products derived from this Software without prior written permission of MetaStuff, Ltd. For written permission, please contact dom4j-info@metastuff.com.

> 4. Products derived from this Software may not be called "DOM4J" nor may "DOM4J" appear in their names without prior written permission of MetaStuff, Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.

> 5. Due credit should be given to the DOM4J Project (http://dom4j.org/).

> THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.