Integrating SonarQube in an Android Application via Docker 🐳

Detailed tech guide for integrating SonarQube for automating code review & generating reports

Hemanshu Varma
ProAndroidDev

--

Photo by Sai Kiran Anagani on Unsplash

Code reviews are often required whether be it a small or enterprise level project to identify bugs, security, performance and vulnerable issues at early stages which contributes to overall code quality.

Since software’s are open to mistakes it is strongly advised to review code in every PR which is tedious in large codebases and involves additional peers effort. To overcome this in fast pace development era, tools such as SonarQube is used to automate this process.

What is Automated Code Review?

Automated code review is the process of automatically reviewing a source code using a predefined set of rules to identify inefficient or suboptimal code.

Wanna learn more about automated code review? Checkout this article

Content

  1. Prerequisite
  2. What is Docker?
  3. Preparing SonarQube in Docker
  4. Configuring Sonar Dashboard
  5. Integrating in Android Application
  6. Bonus

1. Prerequisite

  • Docker installed. Don’t have it? Follow Mac, Windows setup
  • Docker Account
  • Java 11
  • And obviously, Android project :)

2. What is Docker?

Docker is an open-source software designed to facilitate and simplify application development. It is a set of platform-as-a-service products that create isolated virtualized environments for building, deploying, and testing applications.

Image:

A Docker image is an immutable (unchangeable) file that contains the source code, libraries, dependencies, tools, and other files needed for an application to run. Due to their read-only quality, these images are sometimes referred to as snapshots. They represent an application and its virtual environment at a specific point in time. This consistency is one of the great features of Docker. It allows developers to test and experiment software in stable, uniform conditions.

Container:

A Docker container is a virtualized run-time environment where users can isolate applications from the underlying system. These containers are compact, portable units in which you can start up an application quickly and easily. As containers are autonomous, they provide strong isolation, ensuring they do not interrupt other running containers, as well as the server that supports them. Docker claims that these units “provide the strongest isolation capabilities in the industry”. Therefore, you won’t have to worry about keeping your machine secure while developing an application.

TLDR; Image is recipe and Container is cake

3. Preparing SonarQube in Docker

  • Once you have Docker, verify installation by running docker -v in your terminal/command prompt
  • This will print Docker version info. Something like
Docker version 20.10.8, build 3967b7d
  • Start Docker engine and login to your account by docker login command and supplying your username and password. Ignore, if already logged in
  • Running docker images will print list of images installed on Docker. Would print blank if no images are available
  • Time to pull our much awaited SonarQube image from Docker Hub 🐳
  • Run docker pull sonarqube:9.1.0-community and wait until sonar image is fully downloaded. Notice that we’re using the community version which is available for free
C:\Users\hemanshu.varma>docker pull sonarqube:9.1.0-community
9.1.0-community: Pulling from library/sonarqube
a0d0a0d46f8b: Pull complete
ebb745650a9d: Pull complete
8ac639e3bf55: Pull complete
Digest:sha256:628a2c7f2xxxxxc61ec5ddeb0a09c3555a701dxxxxxe796f6582dad8axxxxx90
Status: Downloaded newer image for sonarqube:9.1.0-community docker.io/library/sonarqube:9.1.0-community
  • Now we have sonar image downloaded, verify by running docker images which will print sonarqube image as below
C:\Users\hemanshu.varma>docker images 
REPOSITORY TAG IMAGE ID CREATED SIZE
sonarqube 9.1.0-community 9ff84ae48545 18 hours ago 560MB
  • We’re now ready to run our freshly downloaded docker image into a usable container so that it’s services can be consumed
  • This can be achieved by running below command and prints container ID upon success
docker run -d --name sonarqube -p  9000:9000 sonarqube:9.1.0-community

Full Output:

C:\Users\hemanshu.varma>docker run -d --name sonarqube -p 9000:9000 sonarqube:9.1.0-community c7d8009eexxxxx1d15d0f3e5976e7fxxxxx2075bab15b15ad380xxxxxab36b21

Let’s break down this command to understand:

Basically, we’re trying to run image whose command is in format: docker run [OPTIONS] IMAGE [COMMAND] [ARGS...]

  1. The docker run first creates a writeable container layer over the specified image, and then starts it using the specified command.
  2. -d is used to: Run container in background and print container ID
  3. --name is used to: Assign a name to the container. Here we’re naming it sonarqube
  4. -p is used to: Publish a container’s port(s) to the host
  5. And lastly, our repository with version sonarqube:9.1.0-community
  • Once above command prints container ID successfully, pat your back! 👏This means your instance is up and running
  • Verify this by running docker ps -a command which lists all images with running/exited/stopped status
C:\Users\hemanshu.varma>docker ps -a 
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7d8009ee4aa sonarqube:9.1.0-community "n/opt/sonarqube/bin/…" 38 minutes ago Up 38 minutes 0.0.0.0:9000->9000/ tcp sonarqube

The STATUS Up <TIME> means instance is running

4. Configuring Sonar Dashboard

SonarQube login page
  • Login with default credentials where username: admin and password: admin
  • You may be asked to change default password immediately after login. Ignore, otherwise

4.1 Creating Project:

  1. Now that you’re logged in to your local SonarQube instance, select Manually to run Sonar from local project code
  2. Give your project a Display name, Project key and click the Set Up button. Make sure to retain Project Key, it’ll be required in later stages
  3. It’s time to setup our Repository for Analyzing 🔨
Project setup on Sonar

4.2 Analyzing Repository:

  1. Once Project is created, a repo setup is required where our sonar will be updating stats
  2. To do so, click Locally within just created project
  3. Give token a name and click Generate Token. It is important to retain token safely. This will be used to authenticate
  4. Now, Press Continue
  5. Select your project’s main language under Run analysis on your project, and follow the instructions to analyze your project. Here you’ll download and execute a Scanner on your code (if you’re using Maven or Gradle, the Scanner is automatically downloaded)
SonarQube dashboard with on screen instructions for Android setup
On-screen instructions for Gradle based Android Project

Let’s do some coding now. Enough of CLI and Setup 😉

5. Integrating in Android Application

  • In your project level gradle, add sonar scanner plugin. Latest version can be obtained from here
classpath ‘org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3’
  • Expose this plugin in App level build.gradle by adding,
apply plugin: “org.sonarqube”
  • Add sonarqube block in your app level gradle which has information to authenticate and export report
sonarqube {
properties {
property "sonar.projectName", "My Android App"
property "sonar.projectKey", "@1ph@num3r1ck3y"
property "sonar.sources", "src"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.tests", ["src/test/java"]
property "sonar.test.inclusions", "**/*Test*/**"
property "sonar.exclusions", '**/.gradle/**,' +
"**/androidTest/**," +
"**/R.class," +
"**/BuildConfig.*," +
"**/Manifest*.*," +
"**/android/databinding/*," +
"**/androidx/databinding/*," +
"**/*MapperImpl*.*," +
"**/BuildConfig.*," +
"**/Manifest*.*," +
"**/google-services.json"
}
}

Inclusion/Exclusion Properties can be modified as per requirement. Replace projectKey with key obtained from step: 4.1

  • Sync your Android Project now 🔨
  • Now run below command in terminal and wait until you see BUILD SUCCESSFUL message
gradlew sonarqube -Dsonar.projectKey=HV-Sonar-Demo-7hv3lxxxxx1auceom2j5d2p8 -Dsonar.host.url=http://localhost:9000 -Dsonar.login=2ed5425a24XXXXX8ff4fa219cc68XXXXX108688b

Replace projectKey and login key as obtained from 4.1 and 4.2 respectively

  • Refresh your Sonar project and see results. Yayyy! You made it 🎉
SonarQube dashboard after running script via Android Studio
SonarQube dashboard with Code Analysis report

6. Bonus 🚀

  • Keeping a container up and running is resource consuming. It is best to stop container in such ideal conditions. To do so run:
docker stop <CONTAINER_ID>

Where, container ID can be found by listing containers (docker ps -a command). For instance, docker stop c7d8009ee4aa

  • To start again, run: docker start <CONTAINER_ID>
  • If you run into JAXB Exception, possible causes are:
  1. Using older version of Java. Probably 11 or less for compiling your app
  2. Lower version of gradle tools and distribution. It is recommended to use v4.2.2 of gradle tools and gradle-6.7.1-all distribution
classpath 'com.android.tools.build:gradle:4.2.2'in build.gradle(project level)ANDdistributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zipin gradle-wrapper.properties

Additional Ref: 📝

  1. Docker Commands: https://geekflare.com/docker-commands/
  2. Docker Image vs Container: https://phoenixnap.com/kb/docker-image-vs-container
  3. SonarQube in 2 minutes: https://docs.sonarqube.org/latest/setup/get-started-2-minutes
  4. Latest version of Sonar plugin: https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/ . Also on: https://plugins.gradle.org/plugin/org.sonarqube
  5. SonarQube Android integration on v7.5-community which runs on Java 8: https://tech.olx.com/sonarqube-integration-in-android-application-part-1-37041b0379

That’s it folks. Until next time 👋

--

--

Android Developer at Recro | Google India Scholar | Cynophile | Founder TARA