Icon for gfsd IntelliJ IDEA

The best static analysis tools and linters for Java

The basics of static code analysis and some of the best static analysis & linting tools for Java

This post covers static analysis tools for Java, with a list of some of the best linters and other static analysis tools for Java.

Table of contents:

Static source code analysis greatly supports a software development team’s efforts to maintain high coding standards. While static analysis is becoming quite common, it’s far from being universally practiced. (A 2022 study by Incredibuild states 76% of respondents claimed to use static analysis, while JetBrains' Developer Ecosystem 2023 Report found 16% using such tools.)

This article aims to provide fundamental knowledge on static code analysis, and practical advice on what tools can help you get started with statically analyzing your code.

What is static code analysis?

Static analysis is a way to screen your software code for bugs and defects without executing the program. It’s a form of code review that enables you to examine your source code before running it.

Static analysis helps adhere to established coding standards or conventions, thus contributing to high code quality. It is commonly used to discover problems early on in software development before they become very costly to fix.

Static analysis is mostly done by way of purpose-built tools that can check for coding styles and formatting problems, null pointer exceptions, infinite loops, divisions by zero, typos in regular expressions, code duplications and similar problems in your code.

Static analysis forms the foundation of the testing trophy, and while the testing pyramid doesn’t explicitly mention it, you could think about it as the zeroth step of testing.

Static analysis tools automatically scan your code to compare it against a set of established coding rules. They highlight where the code digresses from these set rules, pinpointing any possible security vulnerabilities, functional defects, and other types of quality problems.

☝️ Thinking about adopting static analysis for security?

Learn more about security testing tools and techniques.

What’s the difference between static vs dynamic code analysis?

Static analysis is a key technique in the shift-left efforts of any developer or team. It should be exercised early – so early, in fact, that static analysis happens before the first time the application is run (e.g. even before unit testing, provided that you’re not working in a TDD environment).

Some static analysis tools are built into IDEs so they can help reveal problems during the coding phase. As we dig further down, we find other differences between static and dynamic code analysis, and some limitations of static analysis:

  • Static analysis doesn’t focus on whether the software works as expected, it doesn’t check functionality against developer intent.
  • Static analysis tools will help you write code that conforms with set coding rules that are clear, enforceable, and not subject to interpretation or any external factors. For instance, avoiding ambiguity in method names may be a key requirement for code, but it’s not something that a code analysis tool can understand and check for.
  • Due to the nature of code analysis (e.g. that it doesn’t interpret code), it can incorrectly identify problems, giving you false positives (and incorrectly pass checks, giving you false negatives).
  • Static analysis isn’t a substitute for dynamic analysis. You need both if you want to build high-quality software.

πŸ€“ Combine static and dynamic testing

Thorough testing doesn’t need to be all that effort-intensive. Here’s how you can generate unit tests for your applications with Symflower:

Benefits of using static code analysis tools

The advantages of using static code analysis focus on three main areas:

  • Early insights: You get feedback as early as possible, e.g. before writing tests (in case your analysis tool runs in the IDE for example), before submitting a code review, or even before you are finished writing up a method. So errors can be fixed while you code and pose the least amount of overhead for fixing.
  • Efficiency: As a step preceding manual code reviews, static analysis tools save time and developer hours while guaranteeing that the types of problems outlined above are discovered early on.
  • Smooth collaboration: Organizations set up coding conventions and standards with the intent that every developer on the team follows them. Static analysis tools help make sure that’s the case, making it easier for team members to collaborate and to apply established best practices as they code.

Static code analysis vs linting

If you’ve heard about linting tools and aren’t sure how they relate to static code analysis, you’re not alone. Let’s clear things up: linting is a type of static code analysis. Linters check for things like syntax errors and formatting issues in your code in real time.

To that end, most linters come integrated into IDEs (e.g. as plugins), so a developer using them will be notified of potential issues and digressions from established coding standards and best practices right as they write code.

Some linters are preconfigured with a baked-in set of rules for each language, but they may be configured to your requirements to match the coding style of your team or organization.

Essentially, you could think of linters as “static code analysis light”. Linters help ensure consistency in coding style, and highlight problems around indentations, line length, unused variables, syntax issues, and more.

Static code analysis is a broader term and such tools also address concerns around security, performance, or compliance with standards. Static analysis tools provide an option for deeper analysis than linters.

Auto-formatting your code

Reformatting code automatically is standard practice in Go programming, but it’s not as widespread in Java projects yet. Essentially, auto-formatting means automatically reformatting code based on the requirements specified by the developer. Some IDEs like IntelliJ IDEA and VS Code offer built-in features to reformat code. In most cases, you can set the reformatter to run automatically upon save, making sure code always compiles and is consistent with established formatting rules and standards across team members. Tools like Spotless can also help you do this.

The best static code analysis tools for Java

In the Java environment, there is not a single solution for all your static analysis needs. Different tools work best for different needs. Let’s see a couple of the most popular static analysis tools for Java.

πŸ‘€ Improve your productivity with these testing tools

Check out our article about the top Java unit testing frameworks & tools

Checkstyle

Checktsyle is a great option for finding basic formatting problems including naming conventions, class or method design problems, and code layout issues. It is an open-source tool that comes with default configurations for Google Java Style and Sun Code Conventions built-in so it’s easy to set up. Naturally, it is a highly configurable tool so you can customize it to suit your needs.

You can use Checkstyle to build static analysis into your CI pipeline (using Github, Jenkins, or Bamboo). Find a list of default Standard Checks on Checkstyle's website.

PMD

PMD provides deeper analysis than Checkstyle, not only focusing on formatting. This open-source code analyzer helps find flaws in your code including unused variables, empty catch blocks, unnecessary objects, etc. It can help pinpoint performance problems and multithreading errors.

With its built-in CPD (copy-paste-detector), PMD can also help identify code duplication in your code base. Like Checkstyle, it comes with built-in rules but lets you configure your own set of coding guidelines.

While it’s a powerful tool, it takes a bit of time to set up (like most open-source solutions do). You can enforce PMD’s rules in your build process with both Maven and Gradle, and it can also be integrated into your pipeline.

Here’s an index of built-in rules available for Java. PMD is available in the most popular IDEs as a plugin (though for VS Code, it’s a third-party add-on).

SpotBugs

Another open-source tool, SpotBugs helps… well, spot bugs in your Java programs. It checks for bug patterns in your code that are likely to be errors.

SpotBugs can scan for bad coding practices and correctness of code, as well as some security and performance problems. Here’s a list of the standard bug patterns reported by SpotBugs.

While SpotBugs doesn’t offer its own plugins, third-party developers offer add-ons for a range of IDEs. There are default integrations with Ant, Maven, Gradle, and Eclipse to help execute static analysis as part of your workflow. You can extend SpotBugs with plugins like find-sec-bugs for finding security bugs, or fb-contrib to check for a range of bug patterns.

Symflower

Symflower is a powerful tool that combines static analysis with symbolic execution and LLMs. Statically analyzing your code, it can automatically generate smart test templates with all the necessary imports, annotations, object initializations, function calls, asserts, and more. After generating smart test templates with a single click, all you need to do is fill in the right values to get useful unit and integration tests.

You can also use the plugin to generate complete, high-coverage unit test suites with meaningful values. Symflower can combine static analysis, symbolic execution, and the best LLMs. The robustness of deterministic analyses combined with the creativity of LLMs allows for higher quality and rapid software development.

Once a test suite was generated, Symflower can provide real-time code diagnostics in your IDE that work like a static analysis tool. Using Symflower, you can not only perform static analysis on your code inputs, but you can also adequately cover them with unit tests, all with minimal manual effort. Here’s an example of Symflower in action:

The Sonar suite

The full Sonar suite combines SonarLint, SonarQube, and SonarCloud. While the Sonar suite is paid (with three pricing levels), SonarLint is a free IDE linter plugin.

SonarQube is a widely used (self-hosted) tool that lets you run static analysis in your Java build pipelines. SonarCloud is the SaaS version of SonarQube.

Use Sonar to check for code quality problems including smells, security vulnerabilities, bugs, suboptimal coding practices, etc. It’s wise to use Sonar in combination with another tool (like Checkstyle) that checks for formatting problems.

Pre- and post-processing with Symflower

symflower lint runs static analysis with preconfigured linting rules on your project. Symflower’s built-in linting rules cover formatting and rules for more idiomatic code as well as simplifications and style rules:

In addition to linting, Symflower also offers static analysis functionality to repair code generated by LLMs. Post-processing with symflower fix executes an automatic repair logic that removes unused imports and adds missing ones, repairs packages, declares undeclared variables, and more.

If you’re using LLMs in your software development workflow, pre- and post-processing with Symflower can have a significant impact on your efficiency. In our benchmarks, scores across 45 applicable models were 22.9% higher with static code repair

Fix disadvantages of LLMs with automatic pre-and post-processing by Symflower

Learn more about using Symflower to generate test templates and test suites, and find out how Symflower supports LLM-powered software development workflows.

Make sure you never miss any of our upcoming content by signing up for our newsletter and by following us on X, LinkedIn, and Facebook.

Try Symflower in your IDE to generate unit test templates & test suites
| 2024-03-10