🔍 Day 10: SonarQube - Hands-On Lab Guide

Practical exercises for code quality analysis (Windows Edition)

Duration: 4 hours | Module: Build & Code Quality

💻 Windows Environment: All commands in this guide are optimized for Windows. Commands are shown for both PowerShell and Command Prompt where applicable.

Lab 1: SonarQube Installation with Docker 🐳

Objective: Install SonarQube using Docker and verify installation
Time: 30 minutes

Prerequisites:

Exercise 1.1: Pull and Run SonarQube Container

1 Open PowerShell as Administrator
  • Press Windows + X
  • Select "Windows PowerShell (Admin)" or "Terminal (Admin)"
2 Check Docker Status
# Verify Docker is running docker --version Docker version 24.0.7, build afdd53b docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3 Pull SonarQube Image
# Pull latest SonarQube image docker pull sonarqube:latest latest: Pulling from library/sonarqube Digest: sha256:abc123... Status: Downloaded newer image for sonarqube:latest
💡 Tip: This download is ~700MB and may take a few minutes depending on your internet speed.
4 Run SonarQube Container
# Run SonarQube on port 9000 with persistent data docker run -d ` --name sonarqube ` -p 9000:9000 ` -v sonarqube_data:/opt/sonarqube/data ` -v sonarqube_logs:/opt/sonarqube/logs ` sonarqube:latest a8f3c21b9d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0
⚠️ Note: The backtick (`) is PowerShell's line continuation character. Make sure to copy the entire command including backticks.
5 Monitor Startup Logs
# Watch container logs docker logs -f sonarqube # Wait until you see these messages: SonarQube is operational Process[web] is up Process[ce] is up Process[es] is up # Press Ctrl+C to exit log view
⏱️ Wait Time: SonarQube takes 1-2 minutes to fully start. Be patient!
6 Verify Installation
# Check container status docker ps CONTAINER ID IMAGE STATUS PORTS NAMES a8f3c21b9d4e sonarqube:latest Up 2 minutes 0.0.0.0:9000->9000/tcp sonarqube # Access SonarQube web interface # Open browser: http://localhost:9000
💡 Tip: You can also type start http://localhost:9000 in PowerShell to open the browser automatically.
✅ Checkpoint: You should see the SonarQube login page at http://localhost:9000

Lab 2: First Login and Configuration 🔐

Objective: Login to SonarQube and change default password
Time: 15 minutes

Exercise 2.1: Login and Change Password

1 Access SonarQube Web UI
  • Open browser (Chrome, Edge, or Firefox)
  • Navigate to: http://localhost:9000
  • You should see the SonarQube login page
2 Login with Default Credentials
  • Username: admin
  • Password: admin
  • Click "Log in" button
3 Change Password (Required)
  • You'll be prompted to change password immediately
  • Enter current password: admin
  • Enter new password (e.g., SonarQube@2026)
  • Confirm new password
  • Click "Update"
💡 Tip: Write down your new password in Notepad! You'll need it for generating tokens.
Suggested password: SonarQube@2026
4 Explore Dashboard
  • You'll see the SonarQube homepage
  • Notice: "Projects" tab (currently empty)
  • Top-right: Your profile icon (admin)
  • Navigation: Projects, Issues, Rules, Quality Profiles, Quality Gates
✅ Checkpoint: Successfully logged in with new password

Lab 3: Create Your First Project 📁

Objective: Create a project in SonarQube and generate access token
Time: 20 minutes

Exercise 3.1: Create Project Manually

1 Create New Project
  • Click "Create Project" button (top-right or center)
  • Select "Manually"
  • Enter project details:
    • Project key: my-first-project
    • Display name: My First Project
  • Click "Set Up" or "Next"
2 Generate Access Token
  • Select "Locally" (analyzing code on your machine)
  • Generate token:
    • Token name: my-first-token
    • Type: Project Analysis Token
    • Expires in: No expiration (for training)
  • Click "Generate"
  • IMPORTANT: Copy the token immediately!
⚠️ Save Your Token:
  1. Click "Copy" button next to the token
  2. Open Notepad (Windows + R, type notepad)
  3. Paste the token (Ctrl+V)
  4. Save file as sonarqube-token.txt on Desktop
Token format: sqp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
3 Select Analysis Method
  • You'll see options: Maven, Gradle, .NET, Other
  • Select "Maven" (we'll start with Java)
  • Note the command shown - we'll use it in Lab 4
  • Don't close this page yet!
✅ Checkpoint: Project created with token saved in Notepad

Lab 4: Analyze a Java Project with Maven 🔍

Objective: Run SonarQube analysis on a Java Maven project
Time: 45 minutes

Exercise 4.1: Create Sample Java Project

1 Create Project Directory
# Open PowerShell # Create directory on Desktop cd $env:USERPROFILE\Desktop mkdir sonar-lab cd sonar-lab # Verify current location pwd Path ---- C:\Users\YourName\Desktop\sonar-lab
2 Create Maven Project
# Create Maven project using archetype mvn archetype:generate ` -DgroupId=com.example ` -DartifactId=calculator ` -DarchetypeArtifactId=maven-archetype-quickstart ` -DinteractiveMode=false [INFO] BUILD SUCCESS [INFO] Project created from Archetype in dir: C:\Users\YourName\Desktop\sonar-lab\calculator # Navigate into project cd calculator
💡 If Maven command not found:
  1. Open Command Prompt as Admin
  2. Type: mvn --version
  3. If not installed, download from: https://maven.apache.org/download.cgi
  4. Extract and add to PATH
3 Add Sample Code with Issues

Open the file: src\main\java\com\example\App.java

You can use Notepad or any text editor:

# Open in Notepad notepad src\main\java\com\example\App.java

Replace the entire content with this code:

package com.example; public class App { public static void main(String[] args) { System.out.println("Calculator App"); // Intentional issues for SonarQube to find: // 1. Unused variable (code smell) int unusedVariable = 10; // 2. Potential null pointer (bug) String text = null; if (Math.random() > 0.5) { text = "Hello"; } System.out.println(text.length()); // Null pointer risk! // 3. Hard-coded credentials (vulnerability) String password = "admin123"; System.out.println("Using password: " + password); // 4. Complex method (code smell) calculateComplexValue(5, 10, 15, 20, 25); } // Method with high complexity public static int calculateComplexValue(int a, int b, int c, int d, int e) { if (a > 0) { if (b > 0) { if (c > 0) { if (d > 0) { if (e > 0) { return a + b + c + d + e; } } } } } return 0; } }

Save and close Notepad (Ctrl+S, Alt+F4)

4 Update pom.xml
# Open pom.xml notepad pom.xml

Find the <properties> section and replace it with:

<properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <sonar.projectKey>my-first-project</sonar.projectKey> </properties>

Save and close (Ctrl+S, Alt+F4)

5 Run SonarQube Analysis

Important: Replace YOUR_TOKEN_HERE with your actual token from Lab 3!

# Build and analyze mvn clean verify sonar:sonar ` -Dsonar.projectKey=my-first-project ` -Dsonar.host.url=http://localhost:9000 ` -Dsonar.login=YOUR_TOKEN_HERE # Example with actual token: mvn clean verify sonar:sonar ` -Dsonar.projectKey=my-first-project ` -Dsonar.host.url=http://localhost:9000 ` -Dsonar.login=sqp_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 [INFO] Analysis report uploaded in 245ms [INFO] ANALYSIS SUCCESSFUL [INFO] You can browse http://localhost:9000/dashboard?id=my-first-project [INFO] BUILD SUCCESS
⚠️ If you get authentication error:
  1. Open your sonarqube-token.txt file from Desktop
  2. Copy the token (make sure no extra spaces)
  3. Replace YOUR_TOKEN_HERE with your actual token
  4. Token should start with sqp_
6 View Results in SonarQube
  • Go to http://localhost:9000
  • Click on "my-first-project"
  • Review the dashboard showing:
    • ✅ Quality Gate status (Passed/Failed)
    • 🐛 Bugs found (should find the null pointer issue)
    • 👃 Code smells detected (unused variable, complex method)
    • 🔒 Security vulnerabilities (hard-coded password)
    • 📊 Code coverage (0% - we have no tests)
✅ Checkpoint: Successfully analyzed Java project and viewed results

Lab 5: Understanding Analysis Results 📊

Objective: Navigate and understand SonarQube results
Time: 30 minutes

Exercise 5.1: Explore Project Dashboard

1 Overall Quality Gate Status
  • At the top: See "Passed" (green) or "Failed" (red) status
  • This shows if code meets quality standards
  • For our buggy code, it might show "Failed" ❌
2 Reliability (Bugs) 🐛
  • Look at the "Reliability" or "Bugs" section
  • Should show: 1 Bug (the null pointer issue)
  • Rating: Probably "C" or "D" (not good!)
  • Click the bug count to see details

You should find:

  • Issue: "NullPointerException might be thrown"
  • Line: Around line 14 (text.length())
  • Severity: Major or Critical
  • Explanation: Variable 'text' might be null
3 Security (Vulnerabilities) 🔒
  • Check "Security" or "Vulnerabilities" section
  • Should show: 1 Vulnerability
  • Click to see details

You should find:

  • Issue: "Hard-coded credentials"
  • Line: Line 17 (String password = "admin123";)
  • Why it's bad: Passwords should never be in source code
  • Solution: Use environment variables or config files
4 Maintainability (Code Smells) 👃
  • Review "Maintainability" or "Code Smells"
  • Should find multiple issues:
    • Unused variable (line 11)
    • High complexity in calculateComplexValue method
    • Nested if statements
  • Note: Technical debt time estimate (e.g., "30min")
5 Code Coverage 📊
  • Currently 0.0% (no tests written)
  • This shows which code is tested by unit tests
  • Industry standard: aim for 80%+ coverage
  • Red = Not covered, Green = Covered by tests

Exercise 5.2: Drill Down Into Issues

1 Click on "Bugs" Count
  • You'll see a list of all bugs
  • Each shows:
    • Severity: Blocker, Critical, Major, Minor, Info
    • File: App.java
    • Line number: Exact location
    • Rule: Why it's flagged
2 Open the Null Pointer Issue
  • Click on the issue in the list
  • You'll see:
    • Code snippet: Highlighted problem area
    • Explanation: "NullPointerException might be thrown as 'text' is nullable here"
    • How to fix: Add null check before using variable
    • Example fix:
// Before (buggy) System.out.println(text.length()); // After (fixed) if (text != null) { System.out.println(text.length()); } else { System.out.println("Text is null"); }
3 Issue Actions

For each issue, you can:

  • Confirm: Mark as real issue to fix
  • False Positive: Not actually a problem (rare)
  • Won't Fix: Intentional (with justification)
  • Comment: Add notes or discussion
  • Assign: Assign to specific developer
  • Change Severity: Adjust priority
✅ Checkpoint: Understand how to read and navigate SonarQube results

Lab 6: Analyze a .NET Project 🔷

Objective: Run SonarQube analysis on a .NET project
Time: 40 minutes

Exercise 6.1: Setup .NET Scanner

1 Install .NET SonarScanner
# Open PowerShell as Administrator # Install global tool dotnet tool install --global dotnet-sonarscanner Tool 'dotnet-sonarscanner' (version '6.0.0') was successfully installed. # Verify installation dotnet sonarscanner --version SonarScanner for .NET 6.0
💡 If .NET SDK not installed:
  1. Download from: https://dotnet.microsoft.com/download
  2. Run installer (dotnet-sdk-8.0-win-x64.exe)
  3. Restart PowerShell
  4. Verify: dotnet --version
2 Create .NET Project
# Navigate to sonar-lab directory cd $env:USERPROFILE\Desktop\sonar-lab # Create Web API project dotnet new webapi -n ProductAPI The template "ASP.NET Core Web API" was created successfully. cd ProductAPI # Verify project structure dir Directory: C:\Users\YourName\Desktop\sonar-lab\ProductAPI Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 2/16/2026 2:30 PM Controllers d----- 2/16/2026 2:30 PM Properties -a---- 2/16/2026 2:30 PM 5879 ProductAPI.csproj -a---- 2/16/2026 2:30 PM 141 Program.cs
3 Create Project in SonarQube
  • Go to http://localhost:9000
  • Click "Create Project"
  • Select "Manually"
  • Project key: product-api
  • Display name: Product API
  • Click "Set Up"
  • Generate token: dotnet-token
  • Copy and save token in Notepad!
  • Select ".NET" as analysis method
4 Run .NET Analysis

Step 1: Begin Analysis

# Replace YOUR_DOTNET_TOKEN with your actual token! dotnet sonarscanner begin ` /k:"product-api" ` /d:sonar.host.url="http://localhost:9000" ` /d:sonar.login="YOUR_DOTNET_TOKEN" SonarScanner for MSBuild 6.0 Default properties file was found at [path] Project key: product-api Version: 1.0.0.0 Organization: - Loading analysis properties... Analysis properties loaded Pre-processing started.

Step 2: Build the Project

dotnet build Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:05.12

Step 3: End Analysis (Upload Results)

dotnet sonarscanner end /d:sonar.login="YOUR_DOTNET_TOKEN" The SonarScanner for MSBuild integration failed: SonarQube was unable to collect the required information about your projects. Possible causes: 1. The project has not been built - the project must be built between the begin and end steps 2. An unsupported version of MSBuild has been used to build the project 3. The begin, build and end steps have not all been launched from the same folder 4. None of the analyzed projects have a valid ProjectGuid and you have not used a solution (.sln) ANALYSIS SUCCESSFUL You can browse http://localhost:9000/dashboard?id=product-api
⚠️ Three-Step Process:
  1. dotnet sonarscanner begin - Start analysis
  2. dotnet build - Build project
  3. dotnet sonarscanner end - Upload results
Must run all three commands in order!
5 View .NET Results
  • Go to http://localhost:9000
  • Click "product-api" project
  • Review:
    • C# specific issues
    • ASP.NET Core code quality
    • Code complexity metrics
    • Security vulnerabilities (if any)
💡 Compare: Notice how .NET template code is cleaner than our intentionally buggy Java code!
✅ Checkpoint: Successfully analyzed .NET project

Lab 7: Understanding Quality Gates 🚦

Objective: Learn about quality gates and how they work
Time: 30 minutes

Exercise 7.1: View Default Quality Gate

1 Access Quality Gates
  • Click "Quality Gates" in top menu
  • You'll see "Sonar way" (default gate)
  • Click on "Sonar way" to view details
2 Review Default Conditions

Default quality gate includes these conditions:

Metric Condition Value Why It Matters
Coverage on New Code is less than 80% New code must be well-tested
Duplicated Lines on New Code is greater than 3% Avoid copy-paste coding
Maintainability Rating is worse than A Code should be easy to maintain
Reliability Rating is worse than A No bugs in new code
Security Rating is worse than A No security vulnerabilities
3 Check Your Project's Status
  • Go back to "Projects"
  • Click on "my-first-project"
  • Top banner shows: "Passed" ✅ or "Failed" ❌
  • Our buggy code probably shows "Failed" ❌
  • Click on the status to see which conditions failed

What you'll see:

  • Reliability Rating = E (because of the bug)
  • Security Rating = E (because of hard-coded password)
  • Maintainability Rating = C or D (because of code smells)
  • These failures prevent the code from being deployed!
4 Understanding Quality Gate Logic
How Quality Gates Work:
  1. Code is analyzed by SonarQube
  2. Metrics are calculated (bugs, code smells, etc.)
  3. Each metric is checked against quality gate conditions
  4. If ANY condition fails → Quality Gate = Failed ❌
  5. If ALL conditions pass → Quality Gate = Passed ✅
  6. In CI/CD: Failed gate = Build fails, code can't be merged

Exercise 7.2: Create Custom Quality Gate (Optional)

1 Create New Gate
  • Go to "Quality Gates"
  • Click "Create" button
  • Name: My Custom Gate
  • Click "Create"
2 Add Custom Conditions
  • Click "Add Condition"
  • Condition 1: Bugs on New Code is greater than 0
  • Condition 2: Code Smells on New Code is greater than 5
  • Condition 3: Coverage is less than 60%
💡 Custom Gates: Different projects may need different quality standards. Legacy code might have relaxed gates, while new critical systems need strict gates.
3 Assign Gate to Project (Optional)
  • In your custom gate, click "Projects" tab
  • Click "Add Project"
  • Select "my-first-project"
  • Re-run Maven analysis to see new gate applied
✅ Checkpoint: Understand quality gates and their purpose in CI/CD

🔧 Troubleshooting Common Issues (Windows)

Issue Windows Solution
Port 9000 already in use Check what's using port:
netstat -ano | findstr :9000
Kill process:
taskkill /PID [PID_NUMBER] /F
Or use different port:
docker run -p 9001:9000 sonarqube:latest
Docker container keeps restarting Check logs:
docker logs sonarqube
Common cause: Insufficient memory
Fix: Docker Desktop → Settings → Resources → Memory (increase to 4GB)
"Authentication error" during analysis 1. Open sonarqube-token.txt from Desktop
2. Copy token (no extra spaces!)
3. Verify token starts with sqp_
4. Generate new token if expired
5. Check project key matches exactly
No results showing after analysis 1. Wait 30-60 seconds for processing
2. Click gear icon (top-right) → Background Tasks
3. Check if processing is complete
4. Verify project key in command matches UI
5. Refresh browser page
Maven not found 1. Download Maven from: https://maven.apache.org/download.cgi
2. Extract to C:\Program Files\Apache\maven
3. Add to PATH: C:\Program Files\Apache\maven\bin
4. Restart PowerShell
5. Verify: mvn --version
.NET command not found 1. Download .NET SDK from: https://dotnet.microsoft.com/download
2. Run installer
3. Restart PowerShell
4. Verify: dotnet --version
Can't access localhost:9000 1. Check if container is running: docker ps
2. Start container: docker start sonarqube
3. Check Windows Firewall settings
4. Try: http://127.0.0.1:9000
Forgot admin password Reset by recreating container:
docker stop sonarqube
docker rm sonarqube
docker run -d --name sonarqube -p 9000:9000 sonarqube:latest
Login again with admin/admin

🎯 Lab Summary

What You've Accomplished:

  • ✅ Installed SonarQube using Docker on Windows
  • ✅ Created and configured projects
  • ✅ Analyzed Java (Maven) projects
  • ✅ Analyzed .NET projects
  • ✅ Understood analysis results (bugs, vulnerabilities, code smells)
  • ✅ Learned about quality gates and their enforcement

Next Steps:

  • 📚 Day 11: Integrate SonarQube with Azure DevOps Pipelines
  • 🔄 Practice: Analyze your own projects
  • 🐛 Fix Issues: Try fixing the bugs in our calculator project
  • 📊 Explore: View different types of rules and metrics
  • 🚀 Prepare: Ensure you have Azure DevOps account ready

📝 Quick Reference - Windows Commands

PowerShell Docker Commands:

# Start SonarQube docker start sonarqube # Stop SonarQube docker stop sonarqube # Remove container docker rm sonarqube # View logs docker logs -f sonarqube # Check status docker ps # Open browser to SonarQube start http://localhost:9000

Maven Analysis (PowerShell):

# Navigate to project cd $env:USERPROFILE\Desktop\sonar-lab\calculator # Run analysis mvn clean verify sonar:sonar ` -Dsonar.projectKey=my-first-project ` -Dsonar.host.url=http://localhost:9000 ` -Dsonar.login=YOUR_TOKEN

.NET Analysis (PowerShell):

# Navigate to project cd $env:USERPROFILE\Desktop\sonar-lab\ProductAPI # Three-step process dotnet sonarscanner begin ` /k:"product-api" ` /d:sonar.host.url="http://localhost:9000" ` /d:sonar.login="YOUR_TOKEN" dotnet build dotnet sonarscanner end /d:sonar.login="YOUR_TOKEN"

Windows File Paths:

# Desktop folder $env:USERPROFILE\Desktop # Example: C:\Users\YourName\Desktop # Lab folder $env:USERPROFILE\Desktop\sonar-lab # Java project $env:USERPROFILE\Desktop\sonar-lab\calculator # .NET project $env:USERPROFILE\Desktop\sonar-lab\ProductAPI

🎉 Day 10 Labs Complete!

You've successfully completed all SonarQube hands-on exercises on Windows!

Ready for Day 11: SonarQube + Azure DevOps Integration

🎓 Skills Acquired:
  • Docker container management on Windows
  • SonarQube project setup and configuration
  • Java Maven project analysis
  • .NET Core project analysis
  • Code quality metrics interpretation
  • Quality gate configuration and enforcement