Introduction

We.. developers.. we spend all our time writing code (and drinking coffee).. but we rarely care about the code quality.. until we get some pressure from a reviewer or from some quality scanner tool.. and as every field in the Java ecosystem, we have many choices when we come to choose a Quality Scanner tool: FindBugs, CheckStyle, PMD and of course the GREATEST SonarQube 😍

I fully worked with SonarQube since January 2014, during my M.Sc. internship to analyze my code and even to check if there are some Security Flaws using the OWASP and SANS Quality Gates.

In this tutorial, I will show you how to get started with SonarQube and how to use it lightly (without even installing it) 😁

Getting Started

In this tutorial, I suppose and I require that you are a Docker addict. ⚠️⚠️⚠️ If it’s not the case , please please please get started to Docker ! It’s a MUST nowadays !!!! ⚠️⚠️⚠️

Preparing THE sample project

The sample project for this tutorial is generated using the Spring Initializr. You can apply this tutorial to ANY MAVEN BASED PROJECT.

You can download the sample project that I generated from here.

Preparing the SonarQUBE Server

All the good stuff is here ! We will just run the official Docker image of SonarQube:

docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 sonarqube:latest

This command will:

  1. Pull the sonarqube:latest image from the Docker Hub
  2. Run as daemon the pulled image and binds the ports 9000 & 9002 to their corresponding ones in the created Docker container

To test your local SonarQube instance, go to the http://localhost:9000:

When the loading finishes, you will get redirected to the SonarQube dashboard screen:

Now, everything is ready, let’s go to the code side 😁

Running the Code analysis from Maven

The operation is extremely easy, it’s just a regular Maven goal to add to your IDE or in your shell πŸ€“ The fabulous Maven command is:

mvn sonar:sonar

Just this ! No plugin to add into your pom.xml 😁 Things will happen:

  1. Maven will download the Sonarqube Maven Plugin
  2. Sonarqube Maven Plugin will get the rules and configuration from the default SonarQube URL which is localhost:9000 which matches our local SonarQube instance.
  3. Sonarqube code scanner will analyze the source code
  4. Sonarqube Maven Plugin will generate some local reports (surefire reports)
  5. Push the report to the default SonarQube URL

The Maven log will look like this:

[INFO] --- sonar-maven-plugin:3.6.0.1398:sonar (default-cli) @ demo ---
[INFO] User cache: /Users/nebrass/.sonar/cache
[INFO] SonarQube version: 7.9.1
[INFO] Default locale: "fr_FR", source code encoding: "UTF-8"
[INFO] Load global settings
[INFO] Load global settings (done) | time=117ms
[INFO] Server id: BF41A1F2-AWzIIuiyloMw5HVAqvFU
[INFO] User cache: /Users/nebrass/.sonar/cache
[INFO] Load/download plugins
[INFO] Load plugins index
[INFO] Load plugins index (done) | time=70ms
[INFO] Load/download plugins (done) | time=168ms
[INFO] Process project properties
[INFO] Execute project builders
[INFO] Execute project builders (done) | time=3ms
[INFO] Project key: com.example:demo
[INFO] Base dir: /Users/nebrass/Downloads/demo
[INFO] Working dir: /Users/nebrass/Downloads/demo/target/sonar
[INFO] Load project settings for component key: 'com.example:demo'
[INFO] Load quality profiles
[INFO] Load quality profiles (done) | time=103ms
[INFO] Load active rules
[INFO] Load active rules (done) | time=3772ms
[WARNING] SCM provider autodetection failed. Please use "sonar.scm.provider" to define SCM of your project, or disable the SCM Sensor in the project settings.
[INFO] Indexing files...
[INFO] Project configuration:
[INFO] 3 files indexed
[INFO] Quality profile for java: Sonar way
[INFO] Quality profile for xml: Sonar way
[INFO] ------------- Run sensors on module demo
[INFO] Load metrics repository
[INFO] Load metrics repository (done) | time=85ms
…
[INFO] Sensor JavaSquidSensor [java]
[INFO] Configured Java source version (sonar.java.source): 8
[INFO] JavaClasspath initialization
[INFO] JavaClasspath initialization (done) | time=15ms
[INFO] JavaTestClasspath initialization
[INFO] JavaTestClasspath initialization (done) | time=2ms
[INFO] Java Main Files AST scan
[INFO] 1 source files to be analyzed
[INFO] Load project repositories
[INFO] Load project repositories (done) | time=11ms
[INFO] 1/1 source files have been analyzed
[WARNING] Classes not found during the analysis : [javax.annotation.meta.When]
[INFO] Java Main Files AST scan (done) | time=406ms
[INFO] Java Test Files AST scan
[INFO] 1 source files to be analyzed
[INFO] 1/1 source files have been analyzed
[INFO] Java Test Files AST scan (done) | time=60ms
[INFO] Sensor JavaSquidSensor [java] (done) | time=1210ms
[INFO] Sensor JaCoCo XML Report Importer [jacoco]
[INFO] Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms
[INFO] Sensor SurefireSensor [java]
[INFO] parsing [/Users/nebrass/Downloads/demo/target/surefire-reports]
[INFO] Sensor SurefireSensor [java] (done) | time=2ms
[INFO] Sensor JaCoCoSensor [java]
[INFO] Sensor JaCoCoSensor [java] (done) | time=1ms
[INFO] Sensor JavaXmlSensor [java]
[INFO] 1 source files to be analyzed
[INFO] Sensor JavaXmlSensor [java] (done) | time=200ms
[INFO] 1/1 source files have been analyzed
[INFO] Sensor HTML [web]
[INFO] Sensor HTML [web] (done) | time=14ms
[INFO] Sensor XML Sensor [xml]
[INFO] 1 source files to be analyzed
[INFO] Sensor XML Sensor [xml] (done) | time=138ms
[INFO] 1/1 source files have been analyzed
[INFO] ------------- Run sensors on project
[INFO] Sensor Zero Coverage Sensor
[INFO] Sensor Zero Coverage Sensor (done) | time=8ms
[INFO] Sensor Java CPD Block Indexer
[INFO] Sensor Java CPD Block Indexer (done) | time=13ms
[INFO] No SCM system was detected. You can use the 'sonar.scm.provider' property to explicitly specify it.
[INFO] 1 file had no CPD blocks
[INFO] Calculating CPD for 0 files
[INFO] CPD calculation finished
[INFO] Analysis report generated in 82ms, dir size=81 KB
[INFO] Analysis report compressed in 24ms, zip size=14 KB
[INFO] Analysis report uploaded in 299ms
[INFO] ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard?id=com.example%3Ademo
[INFO] Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
[INFO] More about the report processing at http://localhost:9000/api/ce/task?id=AWzILjRsloMw5HVAqxNt
[INFO] Analysis total time: 8.298 s

Great ! Let’s go and look what this analysis has generated in the SonarQube Server:

The first thing, on the dashboard, we notice that already the number of projects analyzed has been incrementing. Let’s click on that and see our analyzed project:

Oppaaaaa πŸ₯³! Here is our project’s dashboard ! But 😳 Look ! 😳 There is already a code smell in the freshly generated project?? How come??? πŸ€” Let’s click on that and see what’s wrong?

Yeap ! SonarQube is right 😜 Spring Initializr is generating an empty Test method for us to populate it with our unit tests when we start coding (I hope you do πŸ€žπŸ€“)

Good ! So good !

Let’s add some code to our Spring Boot application, and we will see how things will go with SonarQube. Let’s add this Rest Controller class to our project:

@RestController
@RequestMapping("/api/hello")
public class HelloWorldRestController {
    public String message = "hello world !";

    @GetMapping
    public String sayHello() {
        return message;
    }
}

Next, run the Maven Clean/Install with the SonarQube tests command: mvn clean install sonar:sonar and check again the projects dashboard:

And here 😱😱😱😱😱😱 !! The project FAILED !!! WTF? The command that we did already compiled successfully the project?? What means the project Failed in SonarQube?

This alert means simply that the project failed to pass the Quality Gate 😳 Ok what is a Quality Gate in SonarQube ? Let’s take the definition from the Sonar documentation:

A quality gate is the best way to enforce a quality policy in your organization. It’s there to answer ONE question: can I deliver my project to production today or not?

In order to answer this question, you define a set of Boolean conditions based on measure thresholds against which projects are measured. For example:

  • No new blocker issues
  • Code coverage on new code greater than 80%
  • Etc.

What is interesting here, your company or team can create its own Quality Gate depending of its needs and constraints.

In the section under the project name, there are some elements: Bugs, Vulnerabilites, Code Smells, Coverage and Duplications.

The Code Smells was already 1 (the empty test method body) – So the Quality Gate failure comes from the Vulnerabilites 😱

To see what’s going on, just click on the project name πŸ‘‰ in the Security section, click on the number one vulnerabilities (or the New Vulnerabilites) to list them:

Our vulnerability is:

Oppaaa ! SonarQube dont like the public String messageΒ πŸ€” It asks to make it a static final or to make it non-public (private for example) or to add getters and setters if we want to keep it as like it is 😁

If you want more explanation; just click on See Rule button located in the alert red box of the screen:

If you dont find this great πŸ‘Β  please leave my blog now πŸ˜‚πŸ˜‚πŸ˜‚

This detailed guidance for coding is really wonderful! You dont need to fear from making errors while you are coding ! neither be surprised by code review 😝  comments 🚧

This guidance will be your powerful complimentary tool while coding.

I will make modifications and rescan the project:

Cool ! But, it’s a little heavy to run manually the scanning command every time 😫 Yeah ! I’m lazy ! And many developers are lazy like me ! 😁😁 That’s why the Sonar team thought on us and made for us a great tool called SonarLint !! πŸ₯³πŸ₯³πŸ₯³

Playing with SONARLINT

SonarLint is an IDE extension that helps you detect and fix quality issues as you write code.Β  Like a spell checker, SonarLintΒ squigglesΒ flaws so that they can be fixed before committing code.

SonarLint is available on many IDEs. Unfortunately, it’s not yet available on NetBeans 😫

After installing the plugin to your favourite IDE, when you are coding, you can see immediately if you are doing something messy. If we take the example of our Rest Controller:

Here, in IntelliJ, we see in the SonarLint window, there is the famous “Make message a static final constant or non-public and provide accessors if needed.” that we got before with the Maven scanner on the SonarQube Server dashboard.

There is more to do with SonarLint:

When we talked about the Quality Gates, we said that a company can create its own Quality Gate based on its own needs. There is a very great option in SonarLint that enables it to connect to a specific SonarQube Server to grab specific Quality Gate to use it locally. On this way, you can code locally and be compliant with your team’s quality constraints 😁

Cool ! 😁 Yeah I’m in love with SonarQube ! Please try it ! You will for sure be addicted like me !

Conclusion

SonarQube is for sure one of the most powerful and most used Quality metrics tool in the Java World. We find it in many many many CI/CD pipelines standing on the same side with the Tests runners. Even more, SonarQube metrics and analysis are now a very important criteria to validate the Build & Test step to proceed to staging the project in further steps.

Do SonarQube ! It’s cool & great ! It’s nice and painless 😁 Do it before you will be forced to do it 😜