SonarCloud | Advanced setup | CI-based analysis | SonarScanner for Gradle

On this page

SonarScanner for Gradle

The SonarScanner for Gradle provides an easy way to start SonarCloud analysis of a Gradle project.

The ability to execute the SonarCloud analysis via a regular Gradle task makes it available anywhere Gradle is available (CI service, etc.), without the need to manually download, setup, and maintain a SonarScanner installation. The Gradle build already has much of the information needed for SonarCloud to successfully analyze a project. By configuring the analysis based on that information, the need for manual configuration is reduced significantly.

Prerequisites

  • Gradle 7.3+
  • Java 17

Bytecode created by javac compilation is required for Java analysis, including Android projects.

See also Scanner environment.

Configure the scanner

Installation is automatic, but certain global properties should still be configured. A good place to configure global properties is ~/.gradle/gradle.properties. Be aware that the scanner uses system properties so all properties should be prefixed by systemProp.

systemProp.sonar.host.url=https://sonarcloud.io

# Token generated from an account with 'Execute analysis' permission.
# It can also be set with the environment variable SONAR_TOKEN.
systemProp.sonar.token=<token>

Analyzing

The first step in the process is to activate the scanner in your build. Kotlin DSL is now the default choice for new Gradle builds. However, Groovy is still used by some developers. Apply the SonarQube plugin dependency to your build.gradle.kts file below:

Apply the SonarQube plugin dependency to your build.gradle.kts file: 

plugins {
    id("org.sonarqube") version "4.4.1.3373"
}

sonar {
  properties {
    property("sonar.projectKey", "myProjectKey")
    property("sonar.organization", "myOrganization") 
    property("sonar.host.url", "myHostUrl")
  }
}

If you use Groovy DSL, it is still supported for Gradle 2.1+. In that case, apply the SonarQube plugin dependency to your build.gradle file:

plugins {
  id "org.sonarqube" version "4.4.1.3373"
}

sonar {
  properties {
    property "sonar.projectKey", "myProjectKey"
    property("sonar.organization", "myOrganization")
    property "sonar.host.url", "myHostUrl"
  }
}

Ensure that you declare the plugins in the correct sequence required by Gradle, that is, after the buildscript block in your build.gradle file. More details on https://plugins.gradle.org/plugin/org.sonarqube.

Execute gradle build sonar and wait until the build has been completed, then open the web page indicated at the bottom of the console output. You should now be able to browse the analysis results.

Analyzing multi-project builds

To analyze a project hierarchy, apply the SonarQube plugin to the root project of the hierarchy. Typically (but not necessarily) this will be the root project of the Gradle build. Information pertaining to the analysis as a whole has to be configured in the sonar block of this project. Any properties set on the command line also apply to this project.

// build.gradle
sonar {
    properties {
        property "sonar.sourceEncoding", "UTF-8"
    }
}

Configuration settings shared between subprojects can be specified in a subprojects block.

// build.gradle
subprojects {
    sonar {
        properties {
            property "sonar.sources", "src"
        }
    }
}

Project-specific information is configured in the sonar block of the corresponding project.

// build.gradle
project(":project1") {
    sonar {
        properties {
            property "sonar.branch", "Foo"
        }
    }}

To skip analysis for a particular subproject, set sonar.skipProject to true.

// build.gradle
project(":project2") {
    sonar {
        isSkipProject = true
    }
}

Task dependencies

All tasks that produce output that should be included in the analysis need to be executed before the sonar task runs. Typically, these are compile tasks, test tasks, and code coverage tasks. To meet these needs, the plugin adds a task dependency from sonar on test if the Java plugin is applied. Further task dependencies can be added as needed. For example:

// build.gradle
project.tasks["sonar"].dependsOn "anotherTask"

Sample project

A simple working example is available at this URL so you can check everything is correctly configured in your environment: https://github.com/SonarSource/sonar-scanning-examples/tree/master/sonarqube-scanner-gradle

Analysis property defaults

The SonarScanner for Gradle uses information contained in Gradle's object model to provide smart defaults for most of the standard analysis parameters, as listed below. Note that additional defaults are provided depending on the projects.

Gradle defaults for standard SonarCloud properties

PropertyGradle default
sonar.projectKey[${project.group}:]${project.name} for root module; 
<root module key>:<module path> for submodules
sonar.projectName${project.name}
sonar.projectDescription${project.description}
sonar.projectVersion${project.version}
Do not use your build number as sonar.projectVersion
sonar.projectBaseDir${project.projectDir}
sonar.working.directory${project.buildDir}/sonar

Additional defaults for all projects

PropertyDescriptionGradle default
sonar.gradle.skipCompileIf set to true, it prevents Gradle from compiling before running the sonar task on the project, thus allowing the compilation of a project with one version of the language and the analysis with another (e.g. build with Java 8 as the JDK and run the scanner with Java 17 as the runtime).false

Additional defaults for projects with the base or Java plugins applied

PropertyGradle default
sonar.sourceEncoding${project.compileJava.options.encoding}
sonar.java.source${project.sourceCompatibility}
sonar.java.target${project.targetCompatibility}
sonar.sources${sourceSets.main.allSource.srcDirs}
(filtered to only include existing directories)
sonar.tests${sourceSets.test.allSource.srcDirs}
(filtered to only include existing directories)
sonar.java.binaries${sourceSets.main.output.classesDir}
sonar.java.libraries${sourceSets.main.compileClasspath} (
filtering to only include files; rt.jar and jfxrt.jar added if necessary)
sonar.java.test.binaries${sourceSets.test.output.classeDir}
sonar.java.test.libraries${sourceSets.test.compileClasspath}
(filtering to only include files; rt.jar and jfxrt.jar added if necessary)
sonar.junit.reportPaths${test.testResultsDir}
(if the directory exists)

Additional default for Groovy projects

PropertyGradle default
sonar.groovy.binaries${sourceSets.main.output.classesDir}

Additional defaults when JaCoCo plugin is applied

PropertyGradle default
sonar.jacoco.reportPaths${jacoco.destinationFile}
sonar.groovy.jacoco.reportPath${jacoco.destinationFile}

Additional defaults for Android projects

More default properties apply to Android projects (com.android.applicationcom.android.library, or com.android.test). By default, the first variant of type debug will be used to configure the analysis. You can override the name of the variant to be used using the parameter androidVariant:

// build.gradle
sonar {
    androidVariant 'fullDebug'
}
PropertyGradle default
sonar.sources (for non-test variants)${variant.sourcesets.map} (ManifestFile/CDirectories/AidlDirectories/AssetsDirectories/CppDirectories/JavaDirectories/RenderscriptDirectories/ResDirectories/ResourcesDirectories)
sonar.tests (for test variants)${variant.sourcesets.map} (ManifestFile/CDirectories/AidlDirectories/AssetsDirectories/CppDirectories/JavaDirectories/RenderscriptDirectories/ResDirectories/ResourcesDirectories)
sonar.java[.test].binaries${variant.destinationDir}
sonar.java[.test].libraries${variant.javaCompile.classpath} + ${bootclasspath}
sonar.java.source${variant.javaCompile.sourceCompatibility}
sonar.java.target${variant.javaCompile.targetCompatibility}

Passing manual properties / overriding defaults

The SonarScanner for Gradle adds a SonarQubeExtension extension to a project and its subprojects, which allows you to configure or override the analysis properties.

// build.gradle
sonar {
    properties {
        property "sonar.exclusions", "**/*Generated.java"
    }
}

SonarCloud properties can also be set from the command line, or by setting a system property named exactly like the SonarCloud property in question. This can be useful when dealing with sensitive information (e.g. credentials), environment information, or for ad-hoc configuration.

gradle sonarqube -Dsonar.host.url=http://sonar.mycompany.com -Dsonar.verbose=true

While certainly useful at times, we recommend keeping the bulk of the configuration in a (versioned) build script, readily available to everyone. A SonarCloud property value set via a system property overrides any value set in a build script (for the same property). When analyzing a project hierarchy, values set via system properties apply to the root project of the analyzed hierarchy. Every system property starting with sonar will be taken into account.

Analyzing custom source sets

By default, the SonarScanner for Gradle passes on the project's main source set as production sources, and the project's test source set as test sources. This works regardless of the project's source directory layout. Additional source sets can be added as needed.

// build.gradle
sonar {
  properties {
    property("sonar.projectKey", "myProjectKey")
    property("sonar.organization", "myOrganization")
    property("sonar.host.url", "https://sonarcloud.io")
  }
}

More on configuring properties

Let's take a closer look at the sonar.properties {} block. As we have already seen in the examples, the property() method allows you to set new properties or override existing ones. Furthermore, all properties that have been configured up to this point, including all properties preconfigured by Gradle, are available via the properties accessor.

Entries in the properties map can be read and written with the usual Groovy syntax. To facilitate their manipulation, values still have their “idiomatic” type (File, List, etc.). After the sonar properties block has been evaluated, values are converted to Strings as follows: Collection values are (recursively) converted to comma-separated Strings, and all other values are converted by calling their toString() methods.

Because the sonar properties block is evaluated lazily, properties of Gradle's object model can be safely referenced from within the block, without having to fear that they have not yet been set.

© 2008-2024 SonarSource SA. All rights reserved. SONAR, SONARSOURCE, SONARLINT, SONARQUBE, SONARCLOUD, and CLEAN AS YOU CODE are trademarks of SonarSource SA.

Creative Commons License