How to use Sonar in your project
Probably a few of you have heard about Sonar - a tool that can help you keep your code clean and safe. If you have never heard about it, I encourage you to read the below blog post to grasp how to use it.
For the rest who know it but never used it, I also urge you to take a few minutes on and read how to set up Sonar and why you need it.
What is Sonar
Sonar is a static code analysis tool, a tool that scans your code and tries to detect flaws, bugs, security vulnerabilities, etc. It can also measure test coverage of your code if provided with proper reports. All these features focus on direct code development and help developers build better products.
There are many other tools, which bring the same or very similar functionality. If you want to find a comparison of those tools please take a look at this article: TOP 40 Static Code Analysis Tools. You will find out even more solutions that can suit your needs better.
Yet, you can always create your own custom solution by using a set of products, which are focusing on different aspects of development. Like using Snyk to detect vulnerabilities in your code, or Coveralls to bring code coverage and statistics to the project, and finally SpotBugs (previously known as FindBugs) which uses static analysis to look for bugs in Java code.
As you can see you have many other options to make your code better, and I will just focus on one of them in this blog post.
Project
Instead of showing you some artificial gists not related to anything, I decided to use a real large project with a huge codebase to demonstrate how to use Sonar and why to use it. As I'm a Lead Developer of the Apache Struts project, I choose this project as a typical example of Sonar use case. Moreover, this is an open-source project under Apache 2.0 License, so you are free to use all the examples in your commercial projects :)
Preconditions
To start using Sonar you must have a proper Continues Integration (CI in short) process implemented for your project. There are a few options for how you can use Sonar, which limits how your CI can be implemented. Sonar can be used as a Maven or Gradle plugin, there is support for .NET or Azure. As well, you can use Jenkins extension.
Recently I migrated the Apache Struts from Travis to Github Actions pipeline. Further, as the Apache Software Foundation we are running a Jenkins instance thanks to CloudBees. This means I could you two solutions to implement the CI process and both are in use :D
You can struggle with why we are running two different CI solutions, and the answer is simple: GH Actions are used mainly with PRs while Jenkins (as a bit larger and slower) is used to build and deploy full packages.
Anyway, the project is using Maven as a build tool, which means in both cases we can use the same setup to configure a Sonar scan.
Setup
First, you must create an organization in Sonar and then select a project to be analyzed. Sonar is free of charge for open-source projects with a paid plan for commercial ones.
Sonar supports Maven by using a plugin, in the docs, you will find an exact example of how to use the plugin. Basically, all you need is to define a set of properties (assuming you already created the project in Sonar):
<properties>
<!-- Sonar -->
<sonar.organization>apache</sonar.organization>
<sonar.projectKey>apache_struts</sonar.projectKey>
<sonar.moduleKey>${project.artifactId}</sonar.moduleKey>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
</properties>
It's also a good idea to add code coverage in the same scan run, and this can be easily defined using a Maven profile. I assume you have either JUnit or TestNG setup ready in your project. To import the coverage reports into Sonar you must use a Jacoco Maven plugin, setting it up in a profile is the best option:
<profile>
<id>coverage</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
<goal>prepare-agent-integration</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
<goal>report-integration</goal>
</goals>
<configuration>
<formats>
<format>XML</format>
</formats>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Having this done, you can add another step to your CI pipeline by running the Sonar plugin. You must also provide a token, which you can generate within your account.
It doesn't matter what solution you use, you must just run the Maven build with a proper profile:
mvn -B -Pcoverage verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar
If this is a Jenkins pipeline or GH Actions it's all the same.
Note: I'm running the
verify
phase of the Maven lifecycle to also run integration tests, which is the best approach tbh.
The last final step is to disable automatic Sonar analysis as the analysis will be done via CI, go to \< organization> -> \
Now you are ready to run your CI pipeline!
Visualisation
That's right, it doesn't make sense to run such a tool if the results of running it are not presented publicly. Sonar is no different and allows us to expose all the results in various manners.
When running Sonar analysis via Github Actions, Sonar will post the result of the scan of the PR as a comment:
As you can see you will get direct info about detected bugs, vulnerabilities or code smells, also code coverage is available, which is all you need :) Following the links, you will get more detailed info on what is wrong with a given code.
Another interesting feature is a direct comment on a vulnerable part of the code with a potential solution on how to fix it:
Finally, the last thing is the badges! Each proper project must have badges on its front page, which represents how cool the project is ;-)
Sonar allows you to present each metric by a different badge, just choose what you want:
All these visual assets should help you better understand where the problem is and why you should fix it, just play with them a bit to select what suits you best.
Why use Sonar
After having all these small things done, we can stop and discuss why to use Sonar in the first place. What's the purpose of having it in your toolbox, is it worth investing time and money? And as always the answer is: it depends :)
You must first ask yourself a few questions about what you want to achieve with it. If code coverage is important, if detecting bugs as early as possible makes sense, delivering code without vulnerabilities will make your product safer and cheaper in case of supporting it later, having all these automated with proper hints makes your developers better?
The easiest way is to prepare a list of such questions with cons and pros for each. Maybe you will finally find out that you need just a proper report of code coverage, or that having non-vulnerable code is the most important thing in your business.
Anyway, try to use Sonar especially when you have a chance to play with it in an open-source project (which is free of charge). You can ask: why?
Sonar has been available for Apache projects for a long time, but recently I noticed its value in a day-to-day development. For a long time, I was skeptical that such tools can bring any value, yet after implementing the above process it was worth any penny. Why? Just take a look at the overall statistics of the Apache Struts - poor code coverage, a huge number of outstanding (potential) bugs, tons of code smells - this is a state of 20 years old project. It won't be possible to fix all the problems at once, you aren't able just to sit down and make it better.
You must introduce a process, which follows the old boy scout rule: leave your code better than you found it. This means with each step, with each PR you improve your project. By exposing problems as visual assets, you can easily fix them - first you must know that there is a problem. Starting from scratch with a new project is the best way, you won't waste time and money in the future.
You can start at the beginning or just wait 20 years ;-)