A Guide to Popular Java Static Analysis Tools
Java's popularity as a programming language stems from its platform independence, thanks to the "write once, run anywhere" capability with the Java Virtual Machine (JVM). It excels in object-oriented programming, boasts a rich standard library, and benefits from strong community support.
But as with any programming language, using Java effectively becomes much easier with the help of static code analysis tools. Static code analysis helps developers examine their source code before it goes live, enabling them to catch and fix code errors early in development.
By checking your code before running a program, static analysis tools can reveal coding issues that improve your application architecture and help you understand runtime behaviors better. Static analysis tools can also ensure that your team writes code according to your adopted coding standards and rules.
Use PMD to scan your Java source code and uncover issues such as breaking naming conventions, duplicate code, unused code, and variables to performance and complexity of code.
Here’s a sample of what running PMD looks like:
pmd pmd -R java-basic,java-unusedcode -d Deck.java
/Users/pmd/my/project/Deck.java:35: Avoid unused private fields such as 'classVar2'.
/Users/pmd/my/project/Deck.java:47: Avoid unused private fields such as 'instanceVar3'.
PMD integrates with most popular integrated development environments (IDEs) and build tools, including Eclipse, NetBeans, IntelliJ IDEA, TextPad, Maven, Ant, and Emacs.
jQAssistant is an open-source tool that can help you analyze and control software systems. Its "scan+document=validate" slogan encapsulates its primary use cases: software analytics for system insights, documentation of targeted design and architecture, and validation of data through living documentation.
Use it to help your team automate code analysis and software quality assessment by inspecting and analyzing your codebase against predefined rules, standards, patterns, and constraints.
Featuring a plugin-based architecture, jQAssistant ensures compatibility with different technologies, Java frameworks, and architectural concepts. Plugin customization features are also available.
Findbugs is an open-source static analysis tool that scans Java code for known bug patterns to identify potential defects. All findings by the tool are reported as warnings that point to possible defects that could result in performance issues.
Findbugs reports over 400 warnings in nine categories: correctness, bad practice, dodgy code, performance, malicious code vulnerability, security, and more.
SpotBugs is a fork of FindBugs. Its creators refer to it as the “spiritual successor” of Findbugs, continuing where the first tool left off. It works similarly to FindBugs, but using them both certainly won’t hurt.
SpotBugs categorizes bugs into ten categories: bad practice, correctness, security, performance, dodgy code, experimental, internalization, malicious code vulnerability, multithreaded correctness, and bogus random noise.
It also ranks the bugs by severity to help you prioritize fixing the most critical ones first.
There are several ways of running SpotBugs. Here’s an example of what the command line interface can look like:
H B Eq: org.eclipse.jetty.util.security.Password.equals(Object) checks for operand being a String At Password.java:[line 129]
H B Eq: org.eclipse.jetty.util.ArrayTernaryTrie$Growing.equals(Object) checks for operand being a ArrayTernaryTrie At ArrayTernaryTrie.java:[line 630]
M D Eq: org.hibernate.validator.internal.util.annotationfactory.AnnotationProxy.equals(Object) is unusual At AnnotationProxy.java:[lines 88-111]
M D Eq: com.google.common.reflect.Types$TypeVariableImpl.equals(Object) is unusual At Types.java:[lines 439-459]
H B Eq: com.google.common.reflect.Types$TypeVariableImpl.equals(Object) checks for operand being a reflect.TypeVariable At Types.java:[line 454]
M C Eq: ch.qos.logback.core.joran.spi.ElementSelector overrides equals in ElementPath and may not be symmetric At ElementSelector.java:[lines 146-165]
M C Eq: javassist.bytecode.analysis.MultiArrayType overrides equals in Type and may not be symmetric At MultiArrayType.java:[lines 134-138]
M C Eq: javassist.bytecode.analysis.MultiType overrides equals in Type and may not be symmetric At MultiType.java:[lines 298-307]
M D NP: Method jersey.repackaged.com.google.common.collect.Multiset.equals(Object) overrides the nullness annotation of parameter $L1 in an incompatible way In Multiset.java
H D NP: entry must be non-null but is marked as nullable At Maps.java:[line 1978]
H D NP: entry must be non-null but is marked as nullable At Maps.java:[line 2008]
The first letter in the output refers to the severity of the (potential) bug — L for low, M for Medium, and H for High. The second refers to the category. In this case, P stands for Performance, and D stands for Dodgy Code.
SpotBugs also seamlessly integrates with most popular build tools and includes automated scans and report generation options.
Find Security Bugs
Yet another extension of the FindBugs/SpotBugs family, Find Security Bugs is a SpotBugs plugin that focuses on performing security audits of Java web applications and Android applications. It also works with Kotlin, Groovy, and Scala projects.
The tool detects 141 different security vulnerability types. It covers popular frameworks like Spring-MVC, Struts, and Tapestry and has integration plugins for popular IDEs like Eclipse and NetBeans.
Find Security Bugs prioritizes OWASP TOP 10 coverage and provides extensive references for each related bug pattern it finds.
Spoon, an open-source library, specializes in analyzing and transforming Java source code.
It offers a well-designed AST (Abstract Syntax Tree) with a potent analysis and transformation API.
While capable of parsing source files and building a sound program model, Spoon's strength lies in its powerful API for programmatic Java source code manipulation, automated operations, and diverse applications, particularly code analysis.
Checkstyle is all about ensuring that your code adheres to specific coding standards. The tool is fully configurable to your preferences, enabling it to support different code style conventions. For example, you could use the Sun Code Conventions or Google Java Style, depending on your preferences.
Speaking of configuration, all of this is done in an XML file where you can set which modules are to be used. Here’s an example:
Running this configuration against code results in something like this:
checkstyle -c checkstyle.xml Deck.java
/Users/checkstyle/my/project/Blah.java:0: File does not end with a newline.
/Users/checkstyle/my/project/Deck.java:23: Line has trailing spaces.
/Users/checkstyle/my/project/Deck.java:70: Line has trailing spaces.
Checkstyle ends with 3 errors.
Checkstyle can support just about any coding standard and automatically identify issues with code layout, formatting, class, and method design. It is also compatible with most popular IDEs, including Maven, Eclipse, and IntelliJ IDEA.
Created by Meta, Infer is an open-source static analyzer tailored for mobile and desktop applications, designed to identify Java bugs early in the coding process. This static analysis tool scans your code to provide a list of potential bugs, with a focus on detecting memory leaks and null pointer exceptions.
If your team works with Facebook-related apps, Infer is a great choice for static analysis. It’s deployed within Facebook, running continuously to verify every code modification your team creates when working with apps that connect directly with Facebook Messenger, Instagram, and other apps.
However, outside of Facebook-centric use, its scalability across diverse codebases may necessitate reconfiguration to align with specific project needs.
It integrates seamlessly with build systems like Gradle and Maven.
Combine Complementary Java Tools for Robust Analysis
As with similar tools in other programming languages, all of these Java static analysis tools complement each other, and we recommend you check all of them out to improve code quality and avoid technical debt.
PMD and Checkstyle are already integrated with Codacy. Using Codacy means you’ll get the results from both of these tools (and more) with every commit, plus an expandable list of issues giving additional details on the particular problem and how to solve it.
Integrating your repository with Codacy will also give you a good overview of the status of your project, and help you save tons of time spent on manual code reviews. This way, you and your team can focus on what matters most and ship features faster.
Try Codacy for free by signing up for a free 14-day trial today.