Concise guide for scanning of Gradle-based Java projects

Hello,

I’ve been googling and reading a bunch of articles, but have not found a concise guide explaining in a modern and step by step style how to properly setup scanning of Gradle-based Java project.

What is required to be installed in the build machine
What is required to be installed in SonarQube
What is required to be setup in the gradle.properties
What is required to be setup in the Java project (for the unit tests results)
What is required to be added to the sonar-project.properties file

All of these above would be required in order to:

  1. Scan unit tests
  2. Verify project meets coverage threshold defined in the quality gate

This was very simple to achieve for Node.js-based projects, but I’m having difficulty doing the same for Java (I am not a Java developer, so not as familiar…).

Hi,

Maybe this will help:

https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Gradle

Feel free to tell us what’s missing.

Ann

Hi @ganncamp,
So what I’ve done thus far is the following:

  1. In the build machine, I’ve created a gradle.properties file at ~/.gradle

  2. I edited the file by adding this line:

    systemProp.sonar.host.url=http://****.com:9000/sonarqube
    
  3. In the Java project, I edited the build.gradle file by adding this block:

    plugins {
        id "org.sonarqube" version "2.6.2"
    }
    
  4. Now the guide mentions to run gradle sonarqube, but how do I integrate this in my Jenkinsfile?

  5. Additionally it’s not totally clear to me how a complete sonar-project.properties file would look like.

For our Node.js projects we use SonarQube Scanner in this manner (in the Jenkinsfuile):

withSonarQubeEnv('****') {
  sh "../../../sonar-scanner/bin/sonar-scanner"
}

qualitygate = waitForQualityGate()
if (qualitygate.status != "OK") {
  currentBuild.result = "FAILURE"
  slackSend (...)
}

It’s not clear to me what is the equivalent for Java projects.
These are two aspects(4 & 5) that are well documented for other project types but not at all for Java / Gradle.

Hi,

Here, the SonarQube Scanner for Jenkins docs help.

Regarding sonar-project.properties, since you’re using Gradle to analyze, you don’t need it. The values necessary to analysis with either be picked up automatically by Gradle, or passed through your Gradle file.

 
Ann

OK. It seems it’s now able to analyze the project and display a report in the SonarQube dashboard.

However, the Coverage was not calculated. What am I missing in the setup to get coverage so it could be checked against the quality gate’s coverage threshold?

This is the build.gradle file:

group '****'
version '1.0-SNAPSHOT'

buildscript {
    ext {
        springBootVersion = '2.0.2.RELEASE'
    }
    repositories {
        mavenCentral()
        jcenter()
        maven {
            url "https://plugins.gradle.org/m2/"
        }

        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
            classpath "org.jfrog.buildinfo:build-info-extractor-gradle:latest.release"
            classpath "gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.19.2"
            classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2"
        }
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: "com.jfrog.artifactory"
apply plugin: 'com.palantir.docker'
apply plugin: "org.sonarqube"

bootJar {
    baseName = '****'
    version =  '0.1'

}

repositories {
    mavenCentral()
    jcenter()
    maven {
        url "****"
    }

    maven {
        url '****'
        credentials {
            username = "${artifactory_user}"
            password = "${artifactory_password}"
        }
    }

    maven {
        url '****'
        credentials {
            username = "${artifactory_user}"
            password = "${artifactory_password}"
        }
    }
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

ext['tomcat.version'] = '8.5.32'

dependencies {
    compile(group: '****', name: 'key-pair-generator', version: '0.0.7')
    compile(group: '****', name: 'pepclient', version: '6.1-1')
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile "io.springfox:springfox-swagger2:2.9.0"
    compile "io.springfox:springfox-swagger-ui:2.9.0"
    compile group: 'net.logstash.logback', name: 'logstash-logback-encoder', version: '5.1'
    testCompile("org.springframework.boot:spring-boot-starter-test")
    testCompile( 'org.mockito:mockito-core:2.18.3')
    testCompile 'junit:junit:4.12'
}

sourceSets {
    test {
        java {
            srcDirs = ["src/test/"]
        }
    }
}

docker {
    dependsOn build
    name "${registry}/${microserviceName}:${tag}"
    files bootJar.archivePath
    buildArgs(['JAR_FILE': "${bootJar.archiveName}"])
}

Ian,

You might be interested in this documentation for Code Coverage by Unit Tests for Java Project. That said, if you’re using Gradle the Analyzing with SonarQube Scanner for Gradle documentation indicates that some defaults exist for code coverage reports.

Your scanner logs should indicate if it’s having specific trouble picking up a test coverage report.

Colin

1 Like

Hey @Colin, @ganncamp

Right, so I am following (trying to) the Analyzing with SonarQube Scanner for Gradle topic.

Maybe I’ve missed it in the logs, but I couldn’t spot any log line about coverage. Here are the tests and analysis logs:

analysis.txt (10.4 KB)
tests.txt (10.0 KB)

In addition, in the settings.gradle file I see we have only:

rootProject.name = '****'

In the build.gradle I don’t see any specific mention of a plugin or task that refers to coverage… :no_mouth:

What should I add in order to also have coverage?

Hi,

Are you generating a coverage report? Analysis won’t handle that for you, so that part is a pure Gradle/JaCoCo (presumably) question.

 
Ann

Added Jacobo. Works!