-
Notifications
You must be signed in to change notification settings - Fork 70
Use static analysis
- Update with more options for plugins. See epic #462.
- Edit "Going further" list at bottom, and decide what should be discussed in this page, and what should be links for folks to follow.
There are different stages or phases to static code analysis depending on (1) what is analyzed (source, compiled code, etc), and (2) the purpose of the analysis (bugs, code style, etc).
Analysis subject | Analysis type | Example |
---|---|---|
Source | Build tool version | Enforcer |
Source | Security (dependencies) | DependencyCheck |
Source | Security (vulnerabilities) | CodeQL |
Source | Bugs | PMD |
Source | Style | Checkstyle |
Source | Legacy code | Modernizer |
Compiling | Bugs | The compiler |
Compiling | Bugs | error_prone compiler |
Bytecode | Security | FindSecurityBugs extension to SpotBugs |
Bytecode | Bugs | SpotBugs |
Bytecode | Bugs | PIT mutation testing |
"Linting" is static code analysis with an eye towards style and dodgy source code constructs. The term derives from early UNIX.
Some languages and their compilers do this for you; this is the case, for example, in Golang. See Leverage the compiler for more in depth on this.
On the style and formatting side, having common team agreements is a boon for avoiding bikeshedding, and aids in:
- Reading a code base, relying on a similar style throughout
- Code reviews, focusing on substantive over superficial changes
- Merging code, avoiding trivial or irrelevant conflicts
Code style and formatting are entirely a matter of team discussion and
agreement.
In Java, there is no recommended style, and javac
is good at parsing almost
anything thrown at it.
However, humans reading code are not as well-equipped.
Pick a team style, stick to it, and enforce it with tooling. See Choose your code style for more in depth.
See the section Checkstyle for more details on enforcement and Choose your code style for alternatives to Checkstyle. There is a lot of overlap bewteen "code style" and "static analysis".
Ultimately you want to have consistent build tools for all environments; that is, every build is the same in local and in CI so that you trust outcomes. This means keeping versions the same not just for dependencies but for the tools themselves.
From this need comes the "enforcer" plugins which let you require specific versions of Gradle or Maven and of the JVM.
Gradle will complain at you when there is a newer Gradle version to use, but
this is not quite what you want.
So, it complains at you when you are using an older (or newer) Gradle version.
For you, there is Enforcer Gradle
Plugin.
You are looking at settings.gradle
in this project.
The Maven Enforcer
Plugin lets you
put hard restrictions in your pom.xml
for an exact version of Maven.
You are looking at the maven-enforcer-plugin
plugin configuration in
pom.xml
.
Another static code analysis tool is Modernizer to check of use of obsolete
APIs and types; this is related to but not identical to deprecated APIs. An
example is moving to the JDK's Objects.equals
from Guava's Objects.equal
.
Note that Modernizer works at the bytecode level (not source code), so is suitable for any JVM language, not just Java.
PMD checks for common problems in the source code such as unused variables, empty catch blocks, or unneeded object creation. While SpotBugs focuses on your compiled code, PMD focuses on your source code. See the PMD Best Practices page for more on what problems PMD focuses on.
Both Gradle and Maven support PMD out of the box if enabled in your build (this project enables them).
Documentation is in Gradle plugin.
To open the report for PMD, build locally, then open
<project root>/build/reports/pmd/
.
The reports are:
-
main.html
(production code) -
test.html
(test code) -
integrationTest.html
(integration test code)
Presently the PMD plugin for Gradle does not support CPD (copy-paste detector). An option is to use and external CPD plugin for Gradle.
Documentation is in Maven plugin.
To open the report for PMD, build locally, then open
<project root/target/site/
.
The reports are:
- PMD:
pmd.html
(potential issues) - CPD:
cpd.html
(source code duplicates)
Out of the box, the Maven PMD plugin supports CPD (copy-paste detection).
SpotBugs checks for common problems in the compiled code such as anti-patterns, insecure code, or outdated code patterns. While PMD focuses on your source code, SpotBugs focuses on your compiled code. See the SpotBugs Bug descriptions page for more on what problems SpotBugs focuses on.
Use the Find Security Bugs extension for SpotBugs. See Shift security left for more details.
CodeQL is also provided by GitHub for helping you analyze and search your codebase for vulnerabilities. The way it works is it builds a database of your codebase that can be scanned for potential problems using its own query language. It can easily be setup in github to scan your codebase using query suites. There is a default one, which focuses on finding high risk issues, an extended one which broadens to include ones with lower severity or you can create your own custom suite. These can either be configured to run either on your pipeline or using their CLI tool.
For further reading, you can start here or there is also a built in tutorial which can be found here.
- Edit
config/pmd/custom-rules.xml
to adjust how PMD reviews your code (the sample in this project is from the PMD website.) - To open the report for SpotBugs, build locally and use the
<project root>/build/reports/spotbugs/
(Gradle) or<project root>/target/site/
(Maven) path. Run./mvnw site
for the latter. The path shown in a Docker build is relative to the interior of the container - If you use Google Java coding conventions, consider Spotless which can autoformat your code.
- Consider use of EditorConfig for teams when editor choice is up to each developer. EditorConfig is a cross-IDE standard means of specifying code formatting respected by common code editors (either directly, or through popular plugins)
- To open the report for Checkstyle, build locally and use the
<project root>/build/reports/checkstyle/
path. The path shown in a Docker build is relative to the interior of the container - If you use CodeQL, you can add a badge to your project
README.md
like this project does. You can navigate toactions/workflows/github-code-scanning/codeql
for your project, and use the top-right "Show workflow options" dot-dot-dot for a drop list that includes "Create status badge".
Depending on your choices, you may be interested in other code quality plugins such as:
- Coverity
- Qodana
- Security plugins
- error_prone
- SonarQube
See the code repo for working examples.
This work is dedicated/deeded to the public following laws in jurisdictions
for such purpose.
The principal authors are:
You can always use the "Pages" UI control above this sidebar ☝ to navigate around all pages alphabetically (even pages not in this sidebar), to navigate the outline for each page, or for a search box.
Here is the suggested reading order: