第8章 フィルターファイル

目次

1. フィルターファイルの概要
2. マッチング条件の種類
3. Java 要素名マッチング
4. 留意事項
5. 例
6. 完全な例

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

[注記]計画されている機能

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

1. フィルターファイルの概要

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

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

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

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

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

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

2. マッチング条件の種類

<Bug>

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

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

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

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

<Confidence>

この要素は、特定のバグ信頼度をもつ警告を照合します。 value 属性には、整数値を指定します。すなわち 1 は信頼度(高) 、また、 2 は信頼度(中) 、 3 は信頼度(低) を示します。 <Confidence> は 2.0.0 リリースから <Priority> の後継として取って代わりました。

<Priority>

<Confidence> と同一です。下位互換性を保つため残されています。

<Rank>

この要素は、特定のバグランクをもつ警告を照合します。 value 属性には、 1 から 20 の整数値を指定します。 1 から 4 は最も恐ろしいバグ、 5 から 9 は恐ろしいバグ、 10 から 14 は厄介なバグ, そして 15 から 20 は不安なバグを示します。

<Package>

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

<Class>

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

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

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

<Source>

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

<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 条項に入れることで、どちらか一方のメソッドでマッチさせることができます。

<And>

この要素は、論理積として Match 条項を結合します。 すなわち、 Bug および Confidence 要素を And 条項内に指定することで 特定の信頼度の特定のバグのみ照合することができます。

<Not>

この要素は、内包する子 Match を反転します。 すなわち、 Bug 要素を Not 条項内に指定することで指定したバグ以外のすべてのバグと照合します。

3. Java 要素名マッチング

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

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

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

4. 留意事項

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 要素に加えると期待通りの動作をするでしょう。

5. 例

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>

11. Not フィルター演算子を使用してバグに一致させます。


<!-- テストクラスのバグは無視する。ただし、 JUnit テスト特有のバグは例外とする。 -->
<!-- i.e. filter bug if ( classIsJUnitTest && ! bugIsRelatedToJUnit ) -->
<Match>
  <!-- Match フィルタは論理和と同等 -->

  <Class name="~.*\.*Test" />
  <!-- テストクラスは末尾に「Test」 -->

  <Not>
      <Bug code="IJU" /> <!-- 「IJU」は JUnit テストコード関連のバグコード -->
  </Not>
</Match>

12. 完全な除外フィルター。 Groovy ソースファイルから生成された全クラスを除外します。


<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
    <Source name="~.*\.groovy" />
</Match>
</FindBugsFilter>

6. 完全な例


<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>

     <!-- テストクラスのバグすべて。 JUnit 特有のバグは除く。 -->
     <Match>
      <Class name="~.*\.*Test" />
      <Not>
          <Bug code="IJU" />
      </Not>
     </Match>

</FindBugsFilter>