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
| Property | Purpose |
|---|---|
| sonar.exclusions | Skip generated or vendor files |
| sonar.coverage.exclusions | Keep files out of coverage math only |
| sonar.java.binaries | Point to compiled classes when auto-detection fails |
| sonar.coverage.jacoco.xmlReportPaths | Location 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.
