How Findbugs works with Sonar

In this post I will have a short look at the fantastic Findbugs-tool… Well, fantastic is not the right word, but actually every tools sucks, if you don’t get the idea behind. So here’s my situation:
In the office, we use SonarQube (aka Sonar, but they had a little clinch with namings… anyway!) for checking our sources. Beside Checkstyle, PMD, Squid and other tools, Findbugs is also on board and ready to show us where the big bugs are.
For presentation I’m not allowed to post our top-secret productive sources here, so here comes just a bit samplecode:

package org.jtaddeus.core;
public class Bla {
    public static void main(final String[] args) {
        String arg0 = args[0];
        if (arg0.equals("spongebob")){
            System.out.println("0");
        } else {
            System.out.println("0");
        }
    }
}

Obviously this can happen everybody while refactoring code (or while dreaming of some cold beer).

So, lets build this with little help of Ant:

<project name="builder" basedir="." default="all">

     <property name="src.dir" value="${basedir}/src" />
     <property name="target.dir" value="${basedir}/target" />
     <property name="classes.dir" value="${target.dir}/classes" />
     <property name="findbugs.app.dir" value="${basedir}/findbugs-2.0.3" />
     <property name="findbugs.report.dir" value="${target.dir}/findbugs-reports/" />

     <target name="clean">
          <delete dir="${target.dir}" />
     </target>

     <target name="prepare" depends="clean">
          <mkdir dir="${target.dir}" />
          <mkdir dir="${classes.dir}" />
          <mkdir dir="${findbugs.report.dir}" />
     </target>

     <target name="compile" depends="prepare">
          <javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false"/>
     </target>

     <target name="findbugs" depends="compile">
          <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
               <classpath>
                    <pathelement location="${findbugs.app.dir}/lib/findbugs.jar" />
               </classpath>
          </taskdef>
          <findbugs home="${findbugs.app.dir}" output="html" outputFile="${findbugs.report.dir}/findbugs-report.html">
               <sourcePath path="${src.dir}" />
               <class location="${classes.dir}" />
          </findbugs>
     </target>

     <target name="all" depends="findbugs">

     </target>

</project>

Here is the project-structure in Eclipse:
findbugs-testproject

So, running the default-ant-task „all“ calls the clean-, the preparation-, the compile- and the findbugs-target. As the desired result, we get a findbugs-output.html-file generated with following content:
findbugs-testproject2

Let’s go through it step-by-step:
The Project-Information are not so interesting for us, but the Metrics. There we see, that Findbugs analyzed 6 lines of code, 1 package and 1 class and found 1 Medium Priority Warning. By simply calculating the defects per thousand ncloc, we have a density of 166.67. These are nice information for our managers, but we want to see the real problems. Let’s hop to Warnings and there we’ll find the „Dodgy Code Warning“. „Dodgy“ is another word for „dubious“ and means that there might be a mistake or even not (false-positive). And voila, findbugs found the correct error. But there’s one bad thing: findbugs found the error, but cannot tell exactly where it is, because the location in method is „Unknown“. In this small method, this would work, but imagene good old God-classes with 5.000 or more lines.

This was our first mistake and the solution is to compile the sources with debug-flag set to „on“. Why? Because the detectors of Findbugs don’t care about the sources, only the reporter-part of Findbugs need them. The detectors check the code on bytecode-level and needs for correct bug-pointing the linenumbers and other stuff that is provided within a debug-compilation.
After fixing our ant-script (setting debug to „on“), we’ll get following output:

findbugs-testproject3

Well, that was easy and helps a lot to preserve such mistakes. But in the beginning I wrote something about Sonar. I’ve used Sonar in several projects and it was everytime a fine solution that works. This time, the dev-leader wanted to dive more into Sonar and asked me, if we can use the Eclipse-Findbugs-plugin in connection to the Findbugs-rules that are configured in central Sonar. There you have the perma-links in qality-profiles-menu where you can download the matcher-file of all Findbugs-rules that are active in a specific quality-profile. The guys from architecture-team and the dev-leads invested a lot of time in modifying the rules so they match our project’s needs and we want a simple way of exporting the rules, so our devs can use them also with their own well-known Eclipse. So the rules-file can be exported, but what about including this file to the findugs-eclipse-plugin? We are on a 3.5 Sonar and there the findbugs-configuration is limited to „Confidence“, „Effort“, „Excludes“ and „Timeouts“:
findbugs-testproject4

While the eclipse-plugin-config looks much more … sophisticated:
As first: The „Reporter Configuration“:
findbugs-testproject5
It’s pitty that this comes before „Detector Configuration“, because the reports are more a filter on the bugs that have been detected by Findbugs‘ detectors. Here you can increase the effort, what will result in more memory-consumption and maybe more findings. You can also change the confidence-level, but be careful: on „low“ you will get all bugs and might have a lot of false-positives. You also have the scroller for „Minimum rank to report“. Pre-ranking of bugs might be good for absolute beginners, but if you set it to 20, so you’ll get really all bugs with even least ranks. Again: the higher the minimum rank, the more false-positives you have. Bugs got a rank from 1 to20, and are grouped into categories

  • scariest (rank 1-4)
  • scary (rank 5-9)
  • troubling (rank 10-14)
  • of concern (rank 15-20)

You also are able to set the „Bug categories“ there that also make a bit filtering. Here the „Experimental“ category is slightly interesting.
As second: The „Filter files“-panel:
findbugs-testproject6
Filter-files have one or more matcher to filter only our desired bugs from the thousands of Findbugs-findings. And this is the place, where we should put our Sonar-exported findbugs-filter-file.
A very minimal filter-file for detecting the above bug only would be the following:

<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
  <Match>
    <Bug pattern="DB_DUPLICATE_BRANCHES"/>
  </Match>
</FindBugsFilter>

As third: The „Plugins“-panel:
findbugs-testproject7
Here I just deactivated the „Findbugs Cloud Plugin“, because we’re in a firewalled environment („walled garden“), so it doesn’t make sense to go out and try to reach some clouds.
Last but not least, the „Detector configuration“:
findbugs-testproject8
As written above, the detectors are the core of Findbugs‘ magic. The more detectors you activate the more potentially bugs will be found. In my cases I often check all of them.

So is there a way to get the same results in Eclipse as in Sonar: no… not really. Because the guys from Findbugs rely on there ranking- and priority-system and the SonarQube-guys have their own issue-ranking-system that they will use for all tools like Checkstyle, Squid and so on. So what to do? We found a solution by saying: „Sonar is master!“ Because this is centrally supervised instance with all project-rules that have been marked as worth to check. And all the thing we do on our local machines must help to fix at least (!) the sonar-issues. For that reason we recommend to activate all detectors in Eclipse, set the ranking to 20, make all bugs visibile in the report and use the filter-file that was exported from Sonar.

References:

  • http://findbugs.sourceforge.net/findbugs2.html
  • http://www.sonarqube.org/