SonarQube Maven and Gradle Scanning

Java teams already build with Maven or Gradle. Both tools offer a SonarQube plugin, so analysis becomes one more build step. The plugin knows where compiled classes, test reports, and dependencies live, which removes most manual settings.

The Assembly Line Picture

A build works like a factory line: compile, test, package. The Sonar step sits at the end like a quality camera that photographs each finished product.

 compile ──► test ──► coverage report ──► sonar analysis ──► SonarQube
   │          │             │                   │
 classes   results      jacoco.xml         uses all three

Why Compiled Classes Matter

Java analysis reads bytecode in addition to source files. Rules that follow method calls across files need compiled classes to work well. Always run the build before the Sonar step so the classes exist.

Maven Scanning

Maven needs no installation, because it downloads the plugin on demand. Run one command from the project root.

mvn clean verify sonar:sonar \
  -Dsonar.projectKey=shop-backend \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=YOUR_TOKEN_HERE

What the Command Does

  • clean removes old build output.
  • verify compiles, runs tests, and produces reports.
  • sonar:sonar sends everything to the server.

Store Settings in the POM

Put stable values inside the properties block of pom.xml so the command stays short.

<properties>
  <sonar.projectKey>shop-backend</sonar.projectKey>
  <sonar.host.url>http://localhost:9000</sonar.host.url>
</properties>

Keep the token outside the file. Pass it from an environment variable or your build server.

Gradle Scanning

Gradle needs the plugin declared in build.gradle.

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

sonar {
    properties {
        property "sonar.projectKey", "shop-backend"
        property "sonar.host.url", "http://localhost:9000"
    }
}

Check the plugin portal for the newest version number and use it in place of the sample above. Run the analysis with this command.

./gradlew build sonar -Dsonar.token=YOUR_TOKEN_HERE

Multi-Module Projects

Large Java systems split into modules, such as api, service, and web. Both plugins detect modules automatically and report them as one SonarQube project. Each module contributes its own sources and tests, and the dashboard shows combined numbers with a per-folder breakdown.

Module Layout

 shop-backend
 ├── api        ─┐
 ├── service    ─┼──► one SonarQube project
 └── web        ─┘

Common Properties

PropertyPurpose
sonar.exclusionsSkip generated or vendor files
sonar.coverage.exclusionsKeep files out of coverage math only
sonar.java.binariesPoint to compiled classes when auto-detection fails
sonar.coverage.jacoco.xmlReportPathsLocation of the JaCoCo XML report

Handling Tests and Coverage

The plugin reads test results and coverage files from the build but never runs tests on its own. Configure JaCoCo in your build to write an XML report, then point the property above to that file. The Code Coverage topic covers this setup in detail.

Typical Errors and Fixes

  • No class files found means the build did not compile before analysis. Add the build step ahead of sonar.
  • Project key already exists means another project owns the key. Choose a unique key.
  • Java version mismatch means the build JDK differs from the sources level. Align both versions.
  • Slow analysis on huge repos improves after you exclude generated code.

A Small Walkthrough

Consider a team with a Maven project named shop-backend. A developer runs the verify goal on a laptop, and Maven compiles code, runs unit tests, and writes a JaCoCo report. The sonar goal reads classes and the report, and the plugin uploads everything. The dashboard shows bugs, smells, and coverage within a minute for a small project. Build servers repeat the identical command on every push, so results always match what developers saw locally.

Keeping Tokens Safe

Tokens grant access, so treat them like passwords. Store them as secret variables in your build server, and read them through an environment variable in the command. Never commit tokens to version control. Rotate a token immediately when it appears in a log or a chat message. Create separate tokens for separate pipelines so you can revoke one without breaking the rest.

Quick Recap

Maven uses the sonar:sonar goal, Gradle uses the org.sonarqube plugin, and both read compiled classes plus test reports. Run the full build first, then analyze.