1. 2017-03-14 - Use Sonarqube for Code Inspection; Tags: Use Sonarqube for Code Inspection

    Use Sonarqube for Code Inspection

    Sonarqube is a starting point to find flaws in your source code. This post gives an introduction and demonstrates how to exclude false positives.

    Maven Configuration

    Add in the Apache Maven settings.xml a sonar profile. Replace the sonarqube-server address.

            <!-- Optional URL to server. Default value is http://localhost:9000 -->

    Project Configuration

    Setup your maven project (pom.xml) with a sonar profile. Most developers prefer to put it into a parent pom.


    Run the maven goal for sonar with the profiles: sonar, sonar-verbose.

    mvn sonar:sonar -p sonar -p sonar-verbose

    Following verbose output

    [INFO] --- sonar-maven-plugin:3.2:sonar (default-cli) @ dcc-italy ---
    [INFO] User cache: C:\Users\tan\.sonar\cache
    [INFO] Load global repositories
    [INFO] Load global repositories (done) | time=301ms
    [INFO] User cache: C:\Users\tan\.sonar\cache
    [INFO] Load plugins index
    [INFO] Load plugins index (done) | time=13ms
    [INFO] SonarQube version: 6.1
    [INFO] Default locale: "en_US", source code encoding: "UTF-8"
    [INFO] Process project properties
    [INFO] Load project repositories
    [INFO] Load project repositories (done) | time=169ms
    [INFO] Execute project builders
    [INFO] Execute project builders (done) | time=0ms
    [INFO] Load quality profiles
    [INFO] Load quality profiles (done) | time=20ms
    [INFO] Load active rules
    [INFO] Load active rules (done) | time=201ms
    [INFO] Publish mode
    [INFO] -------------  Scan DCC Italy
    [INFO] Language is forced to java
    [INFO] Load server rules
    [INFO] Load server rules (done) | time=252ms
    [INFO] Excluded sources for coverage:
    [INFO]   **/generated/*.java,**/ddl/*.java, **/jaxb/*.java, **/generated-sources/**/*.java
    [INFO]   **/simulator/**/*.java
    [INFO] Base dir: C:\dev\src\dcc-italy
    [INFO] Working dir: C:\dev\src\dcc-italy\target\sonar
    [INFO] Source paths: pom.xml, src/main/java
    [INFO] Test paths: src/test/java
    [INFO] Source encoding: UTF-8, default locale: en_US
    [INFO] Index files
    [INFO] Excluded sources:
    [INFO]   com/sca/**/ddl/**
    [INFO]   com/tandem/**
    [INFO]   **/wsdl/**
    [INFO]   com/six_group/ao/**/*Dummy.java
    [INFO]   com/telekurs/**/ddl/**
    [INFO]   **/generated/*.java
    [INFO]   **/ddl/*.java
    [INFO] 12 files indexed
    [INFO] 0 files ignored because of inclusion/exclusion patterns
    [INFO] Quality profile for java: Frontoffice Default
    [INFO] Sensor Lines Sensor
    [INFO] Sensor Lines Sensor (done) | time=16ms
    [INFO] Sensor JavaSquidSensor
    [INFO] Configured Java source version (sonar.java.source): 7
    [INFO] JavaClasspath initialization
    [INFO] JavaClasspath initialization (done) | time=22ms
    [INFO] JavaTestClasspath initialization
    [INFO] JavaTestClasspath initialization (done) | time=4ms
    [INFO] Java Main Files AST scan
    [INFO] 8 source files to be analyzed
    [WARNING] Class not found: javax.annotation.Nullable
    [INFO] Java Main Files AST scan (done) | time=1869ms
    [INFO] Java Test Files AST scan
    [INFO] 4 source files to be analyzed
    [INFO] 8/8 source files have been analyzed
    [WARNING] Class not found: javax.annotation.Nullable
    [INFO] Java Test Files AST scan (done) | time=420ms
    [INFO] 4/4 source files have been analyzed
    [INFO] Sensor JavaSquidSensor (done) | time=2845ms
    [INFO] Sensor SCM Sensor
    [INFO] SCM Publisher is disabled
    [INFO] Sensor SCM Sensor (done) | time=1ms
    [INFO] Sensor FindBugs Sensor
    [INFO] Sensor FindBugs Sensor (done) | time=0ms
    [INFO] Sensor SurefireSensor
    [INFO] parsing C:\dev\src\dcc-italy\target\surefire-reports
    [INFO] Sensor SurefireSensor (done) | time=159ms
    [INFO] Sensor JaCoCoSensor
    [INFO] JaCoCoSensor: JaCoCo report not found : C:\dev\src\dcc-italy\target\jacoco.exec
    [INFO] Sensor JaCoCoSensor (done) | time=1ms
    [INFO] Sensor JaCoCoItSensor
    [INFO] JaCoCoItSensor: JaCoCo IT report not found: C:\dev\src\dcc-italy\target\jacoco-it.exec
    [INFO] Sensor JaCoCoItSensor (done) | time=0ms
    [INFO] Sensor JaCoCoOverallSensor
    [INFO] Sensor JaCoCoOverallSensor (done) | time=1ms
    [INFO] Sensor XmlFileSensor
    [INFO] Sensor XmlFileSensor (done) | time=0ms
    [INFO] Sensor Zero Coverage Sensor
    [INFO] Sensor Zero Coverage Sensor (done) | time=19ms
    [INFO] Sensor Code Colorizer Sensor
    [INFO] Sensor Code Colorizer Sensor (done) | time=4ms
    [INFO] Sensor CPD Block Indexer
    [INFO] JavaCpdBlockIndexer is used for java
    [INFO] Sensor CPD Block Indexer (done) | time=74ms
    [INFO] Calculating CPD for 8 files
    [INFO] CPD calculation finished
    [INFO] Analysis report generated in 549ms, dir size=94 KB
    [INFO] Analysis reports compressed in 124ms, zip size=46 KB
    [INFO] Analysis report generated in C:\dev\src\dcc-italy\target\sonar\batch-report
    [INFO] Analysis report uploaded in 63ms
    [INFO] ANALYSIS SUCCESSFUL, you can browse http://sonarqube-server:9000/dashboard/index/com.sca.fo:dcc-italy
    [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://sonarqube-server:9000/api/ce/task?id=AVrMB1PS65C4nw4QRHMg
    [INFO] Executing post-job org.sonar.plugins.buildbreaker.ForbiddenConfigurationBreaker
    [INFO] Executing post-job org.sonar.plugins.buildbreaker.QualityGateBreaker
    [INFO] Executing post-job org.sonar.plugins.stash.StashIssueReportingPostJob

    Suppress Warnings

    Most trivial methods are auto-generated and thus in the eyes of sonar for the human unreadable or a violation against clean readable code. To exclude or to suppress the warnings from sonar, just add the sonarqube rule into the SuppressWarnings tag.

    // Methods should not have too many parameters
    private Line(String alphaIsoCurrencyCode, String numericIsoCurrencyCode, String eurobandIndicator,
      String exchangeRate, String merchantFxRate, String validFromDate, String validFromTime, String validToDate,
      String validToTime, String markupPercentage, String markupDecimalPlacesPrecision) {
        this.alphaIsoCurrencyCode = alphaIsoCurrencyCode;
        this.numericIsoCurrencyCode = numericIsoCurrencyCode;
        this.eurobandIndicator = eurobandIndicator;
        this.exchangeRate = exchangeRate;
        this.merchantFxRate = merchantFxRate;
        this.validFromDate = validFromDate;
        this.validFromTime = validFromTime;
        this.validToDate = validToDate;
        this.validToTime = validToTime;
        this.markupPercentage = markupPercentage;
        this.markupDecimalPlacesPrecision = markupDecimalPlacesPrecision;

    Another example how to exclude multiple rules

    // ignore generated method for sonar
    // Control structures should use curly braces, Statements should be on separate lines
    @SuppressWarnings({"squid:S00121", "squid:S00122"})
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Line line = (Line) o;
        return Objects.equals(getAlphaIsoCurrencyCode(), line.getAlphaIsoCurrencyCode()) &&
                Objects.equals(getNumericIsoCurrencyCode(), line.getNumericIsoCurrencyCode()) &&
                Objects.equals(getEurobandIndicator(), line.getEurobandIndicator()) &&
                Objects.equals(getExchangeRate(), line.getExchangeRate()) &&
                Objects.equals(getMerchantFxRate(), line.getMerchantFxRate()) &&
                Objects.equals(getValidFromDate(), line.getValidFromDate()) &&
                Objects.equals(getValidFromTime(), line.getValidFromTime()) &&
                Objects.equals(getValidToDate(), line.getValidToDate()) &&
                Objects.equals(getValidToTime(), line.getValidToTime()) &&
                Objects.equals(getMarkupPercentage(), line.getMarkupPercentage()) &&
                Objects.equals(getMarkupDecimalPlacesPrecision(), line.getMarkupDecimalPlacesPrecision());