Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Setting Up Static Code Analysis for Java

DZone's Guide to

Setting Up Static Code Analysis for Java

Need help setting up static code analysis for your Java project? Check out this tutorial on how to set up the static code analysis.

· Java Zone ·
Free Resource

Start coding something amazing with our library of open source Cloud code patterns. Content provided by IBM.

Introduction

In this article, we will go through the basic setup of static code analysis for your Java project.

Why is static code analysis important? It helps us to ensure the overall code quality, fix bugs in the early stage of development, and ensure that each developer is using the same coding standards when writing the code.

There are three basic tools that we are going to use for our static code analysis: CheckStyle, Findbugs, PMD.

CheckStyle

CheckStyle is a tool that helps programmers write code that aligns with already agreed upon coding standards. It automatically checks if the code adheres to the coding standards used on a project.

FindBugs

Fine people of the University of Maryland built this fantastic tool for us. What it basically does for us is, of course, find bugs in our code. FindBugs analyses our code and generates a report, giving us a list of all the bugs that could cause a program to misbehave. One of the good examples of the bugs that could be detected are infinite loops, unused variables, security, threading issues, and many more.

PMD

PMD is another useful tool in our static code analyzers toolbox. Beside reporting many coding issues (e.g. possible memory leaks), PMD can check if our code was commented properly if our variables are named properly and our method contains more than the specified number of lines. PMD is highly configurable and the latest releases play quite well with Lombok annotations. Previously, we needed to define custom excluded rules in order for PMD to play nice with Lombok.

Copy/Paste Detector (CPD) is an integrated part of PMD and is used to detect duplicated code in a source code.

Setting Up Static Code Analysis

We are going to use Gradle as our build tool. Gradle already has a set of plugins that we are going to use for our static code analysis.

Static analysis setup files will reside in ./gradle/static-code-analysis folder. Each of our static analysis tools will have its own dedicated folder where we will hold additional configuration files for each of the tools. Finally, we’ll use staticCodeAnalysis.gradle to aggregate all our static code analysis settings. It will contain all the configuration settings needed to run static code analysis for our project.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'de.aaschmid:gradle-cpd-plugin:1.1'
    }
}

apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'pmd'
apply plugin: de.aaschmid.gradle.plugins.cpd.CpdPlugin


Ok, let’s jump into setting the static code analysis.

Once the plugins are included in the build script, we can start configuring each of the plugins. First, we are going to configure the CheckStyle plugin.

Setting CheckStyle

For CheckStyle, we are going to set the ignoreFailures flag, toolVersion, and configFile, which will point to the location of a configuration file. As a base for our configuration file, we are going to use Google Code Style settings. The configurations are basically the same — the only difference is that we are going to use four space instead of two space indentation. And, that’s it. Nothing more needs to be done for CheckStyle. Let’s set up the FindBugs next:

checkstyle {
    toolVersion = '8.12'
    ignoreFailures = false
    configFile = file("${rootGradleDir}/static-code-analysis/checkstyle/checkstyle.xml")
}


We are explicitly setting the plugin not to ignore failures i.e. ignoreFailures flag is set to false. What that basically means is that our project build will fail if we run into any issue during our static code analysis check. If you think about it, this has a lot of sense. Our CI/CD pipeline should fail in case we run upon any issue in our code base. Being it compile failure, unit test failure, code analysis, as long as we have an issue, we shouldn’t be able to continue with our pipeline.

Setting FindBugs

In most cases, we should specify only toolVersion and ignoreFailures. There are other options we could set here, such as specifying which bug detectors are going to be run or to include/exclude lists of files that are going to be checked in our code base. For our example, we will leave the default values here: all default bug detectors will be run, and we are not going to exclude any file from FindBugs detection. 

findbugs {
    toolVersion = '3.0.1'
    ignoreFailures = false
}


Setting PMD

For PMD, besides toolVersion and ignoreFailures, we are going to set the rule sets for our code analysis. We have can set the rule sets in two ways. We can specify them directly inside the PMD plugin configuration using ruleSets array, or we could extract the rule sets to separate the XML file and reference the file using the ruleSetFiles configuration parameter. We are going to choose the latter option since it is more descriptive and allows us to provide exclusions to default rule sets categories. For the codestyle category, we are excluding DefaultPackage  and OnlyOneReturn rules. You can check out ruleset.xml for full setup.

pmd {
    toolVersion = '6.7.0'
    ignoreFailures = false
    ruleSetFiles = files("${rootGradleDir}/static-code-analysis/pmd/ruleset.xml")
    ruleSets = []
    rulePriority = 3
}


Setting CPD

For Copy/Paste bug detection, we need to configure the CPD plugin. First, let’s set the minimumTokenCount to 100. This means that the plugin will detect a duplicate code bug if it finds around  5– 10 lines of the same code in separate places. If only four lines of code are matched, the bug will not be detected. One useful option  — especially if you are using frameworks — is to set the ignoreAnnotations to true. It will allow us to ignore “false positives” and ignore cases where classes or methods have the same 5– 6 lines of annotations. Finally, we’ll enable and generate XML by setting xml.enabled to true.

cpd {
    language = 'java'
    toolVersion = '6.0.0'
    minimumTokenCount = 100 // approximately 5-10 lines
}

cpdCheck {
    reports {
        text.enabled = false
        xml.enabled = true
    }
    ignoreAnnotations = true
    source = sourceSets.main.allJava
}
view raw


For remaining static analysis report plugins, we will enable generation of the HTML report instead of XML one.

tasks.withType(Checkstyle) {
    reports {
        xml.enabled false
        html.enabled true
    }
}

tasks.withType(FindBugs) {
    reports {
        xml.enabled false
        html.enabled true
    }
}

tasks.withType(Pmd) {
    reports {
        xml.enabled false
        html.enabled true
    }
}


Great! We are done with the static analysis code configuration. Now, we just need to include staticCodeAnalysis.gradle into our Gradle build script:

apply from: "${rootGradleDir}/staticCodeAnalysis.gradle"


Running Static Code Analysis

Static code analysis plugins will run with the same Java version used to run Gradle.

Each plugin will add its own dependencies to the Java plugin check task (e.g. pmdMain, cpdMain). Whenever we run ./gradlew clean build, the internally check task will be triggered and static analysis steps will be run for our project. If any of the code analysis steps fail, our build will fail as well.  Static code analysis reports will be generated under ./build/reports.

If in some situations we need to “loose” the specified static code rules, we can always suppress static analysis errors by using @SuppressWarnings annotation. In order to suppress the warning for having too many methods in a class, we could put @SuppressWargning("PMD.TooManyMethods") on the given class.

We advise keeping static analysis “on” for the test classes as well. We should always treat tests as an integrated part of our project. Test code should conform to the same styles/rules we use throughout our project.

Summary

In this post, we went through a short explanation on how to set up the static code analysis for a Java project. Hope you got a good overview on how you can use it in your project, how it can help you to improve overall code quality, and detect bugs in the early stage of project development.

The sample code is available on GitHub. Enjoy static code analyzing!

Use this tool to look at the contents of GitHub and classify code based on the programming language used.  Content provided by IBM Developer.

Topics:
java ,gradle ,static code analysis ,tutorial ,groovy ,xml ,checkstyle ,pmd ,findbugs

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}