8. 过滤文件

师成师成· 更新于 2026-09-28· 阅读 17 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

过滤器文件可用于包含或排除针对特定类和方法的错误报告。本章介绍如何使用过滤器文件。

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> 元素上同时指定了上述多个属性,那么只要缺陷模式匹配其中任意一个指定的模式名称、缩写或类别,就会被匹配到。

作为向后兼容措施,可以使用 <BugPattern> 和 <BugCode> 元素来代替 <Bug> 元素。这两个元素都使用 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 属性用于指定类名的精确匹配或正则匹配模式,role 属性表示类的角色。

作为向后兼容措施,也可以不使用这种类型的元素,而是在 Match 元素上使用 class 属性指定精确的类名,或使用 classregex 属性指定用于匹配类名的正则表达式。

如果 Match 元素既不包含 Class 元素,也不包含 class / classregex 属性,则该谓词将适用于所有类。除非进一步使用适当的方法或字段谓词加以细化,否则这样的谓词很可能会匹配到超出你预期的缺陷实例。

<Source>

该元素用于匹配与特定源文件相关的警告。name 属性用于指定源文件名的精确匹配模式或正则匹配模式。

<Method>

该元素用于指定一个方法。name 用于指定方法名的精确匹配模式或正则匹配模式。params 属性是以逗号分隔的方法参数类型列表。returns 属性是方法的返回类型。role 属性是方法的角色。在 params 和 returns 中,类名必须是完全限定的。(例如,应写成 "java.lang.String" 而不是仅写 "String"。)如果指定了其中某个属性,则必须同时提供另一个属性才能构造方法签名。请注意,你可以只提供 name 属性,或只提供 params 和 returns 属性,也可以三者全部提供。这样你便可以进行各种基于名称和基于签名的匹配。

<Field>

该元素用于指定一个字段。name 属性用于指定字段名的精确匹配模式或正则匹配模式。你也可以根据字段的签名进行过滤——使用 type 属性指定字段的完全限定类型。你可以指定其中任意一个或两个属性,以执行基于名称或基于签名的匹配。role 属性是字段的角色。

<Local>

该元素用于指定一个局部变量。name 属性用于指定局部变量名的精确匹配模式或正则匹配模式。局部变量是指在方法内部定义的变量。

<Or>

该元素将多个 Match 子句以析取方式组合。也就是说,你可以将两个 Method 元素放在一个 Or 子句中,以匹配其中任意一个方法。

<And>

该元素将多个必须同时为真的 Match 子句组合在一起。也就是说,你可以将 Bug 和 Confidence 元素放在一个 And 子句中,以便只匹配具有给定置信度的特定缺陷。

<Not>

该元素对其包含的子 Match 取反。也就是说,你可以将 Bug 元素放在一个 Not 子句中,以匹配除给定缺陷之外的任何缺陷。

3. Java 元素名称匹配

如果 Class、Source、Method 或 Field 的 name 属性以 ~ 字符开头,则属性的其余内容将被解释为 Java 正则表达式,并与相应 Java 元素的名称进行匹配。

请注意,该模式会与元素的完整名称进行匹配,因此需要在模式的开头和/或结尾使用 .* 子句才能实现子串匹配。

模式语法参见 java.util.regex.Pattern 文档。

4. 注意事项

Match 子句只能匹配 bug 实例中实际包含的信息。每个 bug 实例都有一个类,因此通常情况下,按类排除 bug 是可行的。

有些 bug 实例涉及两个(或更多)类。例如,DE(被丢弃的异常)bug 会同时报告包含发生异常丢弃之方法的类,以及表示被丢弃异常类型的类。只有第一个(主要的)类会与 Match 子句进行匹配。所以,假如你想针对类 "com.foobar.A" 和 "com.foobar.B" 屏蔽 IC(初始化循环)报告,就需要使用两个 Match 子句:

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

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

通过显式匹配这两个类,可以确保 IC 缺陷实例无论循环依赖中哪个类恰好被列在缺陷实例的首位,都能被匹配到。(当然,这种方式可能会意外地抑制涉及 "com.foobar.A" 或 "com.foobar.B" 与第三个类的循环依赖。)

许多种类的缺陷会报告其发生所在的方法。对于这些缺陷实例,你可以在 Match 元素中加入 Method 子句,它们应该能按预期工作。

5. 示例

1. 匹配某个类的所有缺陷报告。


     <Match>
       <Class name="com.foobar.MyClass" />
     </Match>
  1. 通过指定测试的缩写来匹配某个类中的特定测试。

     <Match>
       <Class name="com.foobar.MyClass"/ >
       <Bug code="DE,UrF,SIC" />
     </Match>
  1. 通过指定缩写来匹配所有类中的特定测试。

     <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. 匹配特定方法中的特定缺陷模式。


    <!-- A method with an open stream false positive. -->
    <Match>
      <Class name="com.foobar.MyClass" />
      <Method name="writeDataToFile" />
      <Bug pattern="OS_OPEN_STREAM" />
    </Match>

7. 在特定方法中匹配具有给定优先级的特定 bug 模式。


    <!-- A method with a dead local store false positive (medium priority). -->
    <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. 匹配代码库特定部分中的缺陷


    <!-- match unused fields warnings in Messages classes in all packages -->
    <Match>
      <Class name="~.*\.Messages" />
      <Bug code="UUF" />
    </Match>
    <!-- match mutable statics warnings in all internal packages -->
    <Match>
      <Package name="~.*\.internal" />
      <Bug code="MS" />
    </Match>
    <!-- match anonymoous inner classes warnings in ui package hierarchy -->
    <Match>
      <Package name="~com\.foobar\.fooproject\.ui.*" />
      <Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON" />
    </Match>

10. 匹配具有特定签名的字段或方法上的 bug


    <!-- match System.exit(...) usage warnings in void main(String[]) methods in all classes -->
    <Match>
      <Method returns="void" name="main" params="java.lang.String[]" />
      <Bug pattern="DM_EXIT" />
    </Match>
    <!-- match UuF warnings on fields of type com.foobar.DebugInfo on all classes -->
    <Match>
      <Field type="com.foobar.DebugInfo" />
      <Bug code="UuF" />
    </Match>

11. 使用 Not 过滤运算符匹配错误


<!-- ignore all bugs in test classes, except for those bugs specifically relating to JUnit tests -->
<!-- i.e. filter bug if ( classIsJUnitTest && ! bugIsRelatedToJUnit ) -->
<Match>
  <!-- the Match filter is equivalent to a logical 'And' -->

  <Class name="~.*\.*Test" />
  <!-- test classes are suffixed by 'Test' -->

  <Not>
      <Bug code="IJU" /> <!-- 'IJU' is the code for bugs related to JUnit test code -->
  </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>

     <!-- Match all XYZ violations. -->
     <Match>
       <Bug code="XYZ" />
     </Match>

     <!-- Match all doublecheck violations in these methods of "AnotherClass". -->
     <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>

     <!-- A method with a dead local store false positive (medium priority). -->
     <Match>
       <Class name="com.foobar.MyClass" />
       <Method name="someMethod" />
       <Bug pattern="DLS_DEAD_LOCAL_STORE" />
       <Priority value="2" />
     </Match>

     <!-- All bugs in test classes, except for JUnit-specific bugs -->
     <Match>
      <Class name="~.*\.*Test" />
      <Not>
          <Bug code="IJU" />
      </Not>
     </Match>

</FindBugsFilter>

评论

登录后参与评论

正在加载评论…