Scanner Ecosystem: CLI, Maven, Gradle, .NET, and Build Integration: Core Concepts and Mental Model
Understand why scanner choice follows the repository build model, and trace build context, runtime, indexing, report upload, and server computation without treating every scanner as interchangeable.
Learning objectives
- Explain why CLI, Maven, Gradle, and .NET scanners have different invocation contracts.
- Trace source/build evidence through the matching scanner to the same server-side Compute Engine model.
- Separate build-tool runtime, scanner runtime/JRE, compiled outputs, coverage/test reports, scanner cache, and server state.
- Recognize when a build-integrated scanner is safer than forcing a standalone CLI invocation.
- Record scanner/server compatibility and release provenance before analysis.
1. Current baseline and scope
Chapter 06 proved the generic analysis chain. Chapter 07 keeps that
chain but changes the client-side owner. A Python or
build-neutral repository can use Scanner CLI. A Maven project should
normally use SonarScanner for Maven; Gradle has its plugin/task;
MSBuild and dotnet projects use the .NET scanner's
begin/build/end lifecycle. The server still receives an analysis
report and creates a Compute Engine task.
2. Mental model: build ecosystem determines scanner entry point
The client-side path differs by ecosystem; the server-side report-processing path converges.
flowchart TD
R[Repository + revision] --> B{Build ecosystem}
B -->|build-neutral| C[Scanner CLI]
B -->|Maven| M[Maven lifecycle + sonar plugin]
B -->|Gradle| G[Gradle tasks + sonar plugin]
B -->|MSBuild / dotnet| N[begin → build → end]
M --> X[Compiled/test/coverage context]
G --> X
N --> X
C --> A[Indexed files + analysis report]
X --> A
A --> U[Upload]
U --> CE[Compute Engine]
CE --> Q[Issues + measures + Quality Gate]
Scanner CLI starts from a filesystem/project configuration model.
Maven and Gradle can derive properties from their build models and
can coordinate Java bytecode and report locations. The .NET scanner
modifies/observes the build between begin and
end; running only an end command after an
unrelated build is not equivalent.
3. State stores that move independently
| State | Owner | Examples | Evidence |
|---|---|---|---|
| Build model | Maven/Gradle/MSBuild/dotnet | modules, source sets, target frameworks |
mvn -version, Gradle tasks,
dotnet --info
|
| Scanner/plugin | Scanner distribution or build plugin | CLI 8.1.0.6389, Maven 5.7.0.6970, Gradle 7.3.1.8318, .NET 11.2.1.137242 | scanner/plugin version output or dependency metadata |
| Scanner JRE/runtime | scanner host / auto-provisioner | system Java vs downloaded JRE | scanner logs and runtime evidence |
| Compiled context | build output |
target/classes, Gradle classes, .NET assemblies
|
artifact tree + build logs |
| Test/coverage reports | test/coverage tools | JaCoCo XML, TRX, coverage XML | report paths and timestamps |
| Cache | scanner user home |
~/.sonar or configured
SONAR_USER_HOME
|
cache path/ownership, not cache contents as project truth |
| Analysis report/task | scanner + server |
.scannerwork, report-task.txt, CE
task
|
task ID/status |
| Governed result | SonarQube project policy | issues/measures/gate | UI/API after CE success |
4. Scanner selection rule
| Repository | Preferred scanner | Why | Wrong shortcut |
|---|---|---|---|
| Plain/build-neutral sources | Scanner CLI | Explicit filesystem/indexing model | Using a build plugin when there is no matching build |
| Maven | SonarScanner for Maven | Reads Maven reactor/build metadata | Generic CLI used without compiled/module context |
| Gradle | SonarScanner for Gradle | Understands Gradle project/source-set model | Standalone scan from arbitrary subdirectory |
| .NET / MSBuild | SonarScanner for .NET | Analysis is integrated with the build lifecycle | CLI used as if C# build context were optional |
5. Runtime model: build JVM is not always scanner JVM
Current scanner generations support JRE auto-provisioning. That means the Java used by Maven or Gradle to run the build is not automatically proof of the Java runtime used by the scanner engine. Current Maven scanner documentation requires Maven 3.2.5+ and Java 21 when provisioning is not used, while Java 11+ can bootstrap current auto-provisioning. Current Gradle documentation similarly distinguishes normal Java requirements from the lower bootstrap requirement with auto-provisioning.
The .NET scanner no longer requires you to preinstall Java in the normal modern path because it provisions the scanner Java runtime. If provisioning is deliberately disabled or network policy prevents it, record the exact fallback runtime rather than copying an old “Java 17” tutorial.
6. Compiled context is part of the analysis input
Java analysis requires compiled bytecode. Maven and Gradle are good
examples of why scanner choice belongs next to the build:
mvn clean verify …:sonar or an appropriate Gradle build
followed by sonar gives the scanner the compilation
context produced by the same build. If you delete
target/classes or point
sonar.java.binaries at an empty/wrong directory, static
analysis cannot infer the same semantic information from source text
alone.
7. Scanner cache is reusable dependency state, not analysis truth
Scanners use a user-home cache, normally under
~/.sonar; SONAR_USER_HOME can relocate it.
CI systems commonly cache this directory to avoid repeated
analyzer/JRE downloads. Cache reuse improves speed but must not be
treated as project evidence. Record scanner versions and effective
inputs separately, and diagnose cache permission/corruption problems
without deleting first-failure evidence blindly.
8. Read-only inventory before choosing a scanner
git status --short
git rev-parse HEAD
sonar-scanner --version || true
mvn -version || true
gradle --version || true
dotnet --info || true
find . -maxdepth 2 -type f \( -name pom.xml -o -name build.gradle -o -name build.gradle.kts -o -name '*.sln' -o -name '*.csproj' -o -name sonar-project.properties \) -print
Do not install a scanner until you know which build descriptor exists, which build tool owns compilation, and whether previous test/coverage reports are expected.
9. DevOps connection: pin the client path like any other build dependency
Scanner drift can change runtime requirements, indexing behavior, dependency resolution, telemetry, or compatibility even when the server is unchanged. A reviewable pipeline therefore records the project revision, build tool/version, scanner/plugin version, runtime/provisioning mode, report paths, task ID, and server release. A centrally “latest” scanner with no provenance is operationally weaker than a controlled update process.
Knowledge check
Why is Scanner CLI not automatically the best choice for every repository?
Because build-integrated scanners can obtain native build/module/compiled context that a generic filesystem scan may not reproduce.
Does the Java used to launch Maven always equal the scanner-engine Java?
No. With current JRE auto-provisioning the scanner engine can use a provisioned JRE; record both relevant runtimes.
What is special about .NET analysis?
The scanner wraps the build with a begin/build/end lifecycle so the build itself contributes analysis context.
Why preserve compiled bytecode for Java analysis?
Java analyzers require bytecode context; source alone is not equivalent.
What does the scanner cache prove?
Only that reusable scanner artifacts exist. It does not prove which revision, files, parameters, or gate were analyzed.
Official references and version notes
- SonarScanner CLI — build-neutral scanner usage, cache behavior, project base directory, and Docker notes.
- SonarScanner CLI 8.1.0.6389 — official release provenance.
- SonarScanner for Maven and release 5.7.0.6970.
- SonarScanner for Gradle and release 7.3.1.8318.
- SonarScanner for .NET usage and release 11.2.1.137242.
- Scanner environment general requirements and JRE auto-provisioning.
- Official scanner examples — recommended scanner choice by build ecosystem.
- Apache Maven downloads — Maven 3.9.16 is the current stable Maven baseline used in the Maven lab.
Rechecked on 2026-09-07. The chapter targets local/private Community Build 26.9.0.129388. Current release baselines used for reproducible examples are Scanner CLI 8.1.0.6389, SonarScanner for Maven 5.7.0.6970, SonarScanner for Gradle 7.3.1.8318, and SonarScanner for .NET 11.2.1.137242. Mandatory execution uses CLI plus Maven; Gradle and .NET are optional executable extensions when their build prerequisites are installed. JRE auto-provisioning is kept enabled unless a lesson explicitly demonstrates the system-Java boundary. Re-check current scanner/server compatibility before future runs because scanner release trains move independently.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.