The previous article introduced FindBugs — a legendary bytecode-level bug checker, but one that stopped being maintained in 2016. Fortunately the community did not let it go quiet: as FindBugs’ official successor, SpotBugs inherits its entire set of bug patterns and its analysis engine, and keeps adding new features and support for new versions of Java. If you are looking for a bytecode-level static analysis tool that is “still alive”, SpotBugs is the answer.
What SpotBugs Is
SpotBugs is a community fork of FindBugs, started at the end of 2016 and maintained by the original FindBugs contributors. Its positioning is the direct inheritance and evolution of FindBugs:
- Fully compatible: every FindBugs bug detector is kept, and the results are consistent
- Continuously updated: supports the new syntax and APIs of Java 8, 9, 10 and 11
- An active community: stable release cadence, timely bug fixes
- A plugin ecosystem: security-checking capabilities can be extended with plugins such as
findsecbugs
In one sentence: wherever FindBugs runs, SpotBugs runs too, but what SpotBugs can detect is not necessarily something FindBugs can find.
Getting Started
Maven Integration
SpotBugs provides its own Maven plugin, which is more concise to use than FindBugs’:
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>3.1.8</version>
<configuration>
<effort>Max</effort>
<threshold>Low</threshold>
<xmlOutput>true</xmlOutput>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
Running the check:
mvn verify
# Or run it directly
mvn spotbugs:check
# View the report (with a graphical interface)
mvn spotbugs:gui
Gradle Integration
plugins {
id 'com.github.spotbugs' version '1.6.2'
}
spotbugs {
effort = 'max'
reportLevel = 'low'
}
tasks.withType(com.github.spotbugs.SpotBugsTask) {
reports {
xml.enabled = false
html.enabled = true
}
}
Migrating From FindBugs
If you are already using FindBugs, migrating to SpotBugs costs almost nothing:
- Maven: swap
findbugs-maven-pluginforspotbugs-maven-plugin; the configuration parameters are basically compatible - Annotations: replace
import edu.umd.cs.findbugs.annotations.*withimport edu.umd.cs.findbugs.annotations.*(the annotation namespace is retained, so no code changes are needed) - Filter files: fully compatible, no modification required
What’s New in SpotBugs
Support for New Versions of Java
FindBugs stopped at the Java 8 era. SpotBugs keeps following along:
- Java 9/10/11: supports
vartype inference, the module system and new APIs - Java 8 Lambda: improved analysis of lambdas and the Stream API
- Try-with-resources: supports analysing the auto-closing resource idiom
New Detectors
SpotBugs adds several bug detectors that FindBugs does not have, for example:
- DMI_RANDOM_USED_ONLY_ONCE: a
Randomobject is used only once, the seed never changes, so every result is the same - RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE: a redundant null check on a value already known to be null
- RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT: a method with no side effects is called and its return value ignored
The Plugin Mechanism
SpotBugs supports plugins to extend its checking capabilities. The one most worth knowing about is Find Security Bugs:
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>3.1.8</version>
<configuration>
<plugins>
<plugin>
<groupId>com.h3xstream.findsecbugs</groupId>
<artifactId>findsecbugs-plugin</artifactId>
<version>1.8.0</version>
</plugin>
</plugins>
</configuration>
</plugin>
Once installed, the security issues it can detect include:
- SQL injection
- XSS cross-site scripting
- Hard-coded passwords
- Insecure cryptographic algorithms (MD5, SHA1)
- Path traversal vulnerabilities
A Real-World Configuration Example
A complete, production-grade SpotBugs configuration:
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>3.1.8</version>
<configuration>
<effort>Max</effort>
<threshold>Low</threshold>
<xmlOutput>true</xmlOutput>
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
<!-- Integrate the security detection plugin -->
<plugins>
<plugin>
<groupId>com.h3xstream.findsecbugs</groupId>
<artifactId>findsecbugs-plugin</artifactId>
<version>1.8.0</version>
</plugin>
</plugins>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals><goal>check</goal></goals>
</execution>
</executions>
</plugin>
Commonly Used Exclusion Configuration
spotbugs-exclude.xml:
<FindBugsFilter>
<!-- Ignore all auto-generated code -->
<Match>
<Source name="~.*generated.*"/>
</Match>
<!-- Ignore direct-field-assignment warnings in DTOs -->
<Match>
<Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2"/>
<Class name="~.*Dto"/>
</Match>
<!-- Ignore a specific issue in a specific class -->
<Match>
<Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"/>
<Class name="com.example.legacy.OldService"/>
</Match>
</FindBugsFilter>
Suppressing a Specific Warning
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@SuppressFBWarnings(
value = "DMI_RANDOM_USED_ONLY_ONCE",
justification = "此处只需要一个随机值,不是 Bug")
public class RandomTokenGenerator {
// ...
}
Priority and Severity
SpotBugs carries over FindBugs’ priority system:
| Rank | Severity | Description |
|---|---|---|
| 1-4 | Scariest | Almost certainly a bug, must be fixed |
| 5-9 | Scary | Very likely a bug, strongly recommended to fix |
| 10-14 | Troubling | Possibly a bug, worth checking |
| 15-20 | Normal | A style issue, improvement suggested |
It is recommended to set the threshold to Low in CI (that is, report every issue), but have the Quality Gate block only on rank 1-14 issues (that is, set threshold to Low so the team sees all the problems in the report, while only the severe ones are mandatory to fix).
IDE Integration
IntelliJ IDEA
Install the SpotBugs plugin (note: not the FindBugs plugin), and configure the rules under Preferences → Other Settings → SpotBugs. The plugin supports highlighting issues inline in the code.
Eclipse
Install the SpotBugs Eclipse Plugin; it can scan in real time, mark the offending lines of code and offer quick-fix suggestions.
Summary
SpotBugs is FindBugs’ “legitimate sequel” — it inherits all of its capabilities and keeps evolving. For any Java project, if you can choose only one static bug-checking tool, SpotBugs is the most recommended: it analyses bytecode, its bug patterns are precise, its false-positive rate is low and its ecosystem is mature. Paired with the Find Security Bugs plugin, it also covers security vulnerability detection.
The next article is the last in this series, introducing SonarQube — a comprehensive code quality platform that “bundles all of these tools together”.
A small step forward every day is a new height!