过滤文件

qianmoQqianmoQ· 更新于 2026-09-30· 阅读 17 分钟· 0 次阅读

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

过滤文件

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

过滤文件简介

从概念上讲,过滤器会依据一组条件对缺陷实例进行匹配。通过定义过滤器,你可以挑选出需要特殊处理的缺陷实例;例如,将其从报告中排除或纳入报告。

过滤文件是一个 XML 文档,其顶层元素为 FindBugsFilter,该元素包含若干 Match 子元素。每个 Match 元素都表示一个应用于所生成缺陷实例的谓词。通常,过滤器用于排除缺陷实例。例如:

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

不过,过滤器也可以用来特意选出需要报告的缺陷实例:

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

Match 元素包含子元素,这些子元素是该谓词的合取项。换言之,只有当其中每个子元素都 true 时,该谓词才会 true。

Match 子句的类型

<Bug>

此元素指定要匹配的特定 bug pattern 或 patterns。pattern 属性是一个以逗号分隔的 bug 模式类型列表。要查找特定警告对应的 bug 模式类型,可以查看 -xml 输出选项生成的输出(即 BugInstance 元素的 type 属性),或者参阅 Bug 描述。

如需进行更粗粒度的匹配,请使用 code 属性。它接受一个以逗号分隔的 bug 缩写列表。如需进行最粗粒度的匹配,请使用 category 属性,它接受一个以逗号分隔的 bug 类别名称列表:CORRECTNESS、MT_CORRECTNESS、BAD_PRACTICE、PERFORMANCE、STYLE。

如果在同一个 元素上指定了上述多个属性,则所有与所指定的模式名称、缩写或类别中任意一项匹配的 bug 模式都会被匹配。

作为向后兼容措施,可以使用 和 元素来代替 元素。这两个元素都使用 name 属性来指定可接受的值列表。这些元素的支援可能会在未来版本中移除。

<Confidence>

此元素用于匹配具有特定缺陷置信度的警告。value 属性应为整数值:1 匹配高置信度警告,2 匹配普通置信度警告,3 匹配低置信度警告。<Confidence> 在 2.0.0 版本中取代了 <Priority>。

<Priority>

与 <Confidence> 相同,为向后兼容而保留。

<Rank>

此元素用于匹配至少具有指定 bug 等级的警告。value 属性应为 1 到 20 之间的整数值,其中 1 到 4 为“最可怕”,5 到 9 为“可怕”,10 到 14 为“令人不安”,15 到 20 为“值得关注”的 bug。

<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 属性用于指定局部变量名称的精确匹配或正则匹配模式。局部变量是指在方法内部定义的变量。

<Type>

此元素匹配与特定类型相关的警告。descriptor 属性用于指定类型描述符的精确匹配或正则表达式匹配模式。如果描述符以 ~ 字符开头,则属性内容的其余部分将被解释为 Java 正则表达式。role 属性是类的角色,typeParameters 是类型参数。role 和 typeParameters 均为可选属性。

<Or>

该元素将 Match 子句作为析取项进行组合。也就是说,你可以在一个 Or 子句中放入两个 Method 元素,以便匹配其中任一方法。

<And>

此元素组合了 Match 子句,且两者都必须求值为 true。也就是说,你可以在一个 And 子句中放置 Bug 和 Confidence 元素,以便仅匹配具有给定可信度的特定缺陷。

<Not>

此元素会对所包含的子元素 Match 取反。也就是说,你可以在 Bug 子句中放入一个 Not 元素,以便匹配除给定缺陷之外的所有缺陷。

Java 元素名称匹配

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

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

有关模式语法,请参阅 java.util.regex.Pattern 文档。

注意事项

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

某些缺陷实例涉及两个(或更多)个类。例如,DE(被丢弃的异常)缺陷会同时报告包含发生异常丢弃的方法的类,以及表示被丢弃异常类型的类。只有第一个(主要)类会与 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 子句,它们会按预期生效。

示例

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

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

通过指定缩写匹配类中的特定测试

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

通过指定缩写来匹配所有类中的特定检测项

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

通过指定类别匹配所有类中的特定测试

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

按缩写匹配类中指定方法的缺陷类型

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

在特定方法中匹配特定的错误模式

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

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

匹配代码库特定部分中的缺陷

<!-- 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 anonymous inner classes warnings in ui package hierarchy -->
<Match>
<Package name="~com\.foobar\.fooproject\.ui.*" />
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON" />
</Match>

按特定签名匹配字段或方法上的缺陷

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

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

用于匹配从 Groovy 源文件生成的所有类的完整排除过滤器文件

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

完整示例

<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter
        xmlns="https://github.com/spotbugs/filter/4.8.4"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://github.com/spotbugs/filter/4.8.4 https://raw.githubusercontent.com/spotbugs/spotbugs/4.8.4/spotbugs/etc/findbugsfilter.xsd">
    <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>

评论

登录后参与评论

正在加载评论…