Setting up SonarQube for Android Gradle project to improve code quality

I’m working on a new Android project which I inherited. Well, I forked it because I didn’t feel welcomed to contribute to the project and I see a lot of places where improvements are needed.

First, I need to improve the codebase. Previous developers didn’t care about any Java coding guidelines from Oracle, Google, CERT or even Android. Some of the problems I have to solve now are:

  • inconsistent style
  • catch (Exception e){}
  • catch(Throwable e){}
  • ArrayList<Object> list = new ArrayList<String>()
  • complex methods – if {switch {for {if {else {}}}}
  • new Thread().start()

To quickly start clean-up and identify those problems, different static code analysis tools can be used; one of them is SonarQube.

First, download SonarQube from their official website and extract the zip.

Then you can try SQ without setting up database. Just go to extracted folder, bin directory, where you will see supported platforms:

➜  bin ls -1
jsw-license
linux-x86-32
linux-x86-64
macosx-universal-64
windows-x86-32
windows-x86-64

In my case, I just run:

➜  sonarqube-5.4 ./bin/linux-x86-64/sonar.sh start

After a few seconds your SQ is running on http://localhost:9000/
sonarqube evaluation

If you plan to use it more often, it’s recommended to setup a database; it can be MariaDB, PostgreSQL or any other supported.
On my setup I use MariaDB, just because it’s most common. All you need to do, is to create a user in your database server and configure it in config/sonar.properties .

For MySQL/MariaDB find and remove comment tag from those lines:

 11 # User credentials.
 12 # Permissions to create tables, indices and triggers must be granted to JDBC user.
 13 # The schema must be created first.
 14 sonar.jdbc.username=root
 15 sonar.jdbc.password=password
 16 
 17 #----- Embedded Database (default)
 18 # H2 embedded database server listening port, defaults to 9092
 19 #sonar.embeddedDatabase.port=9092
 20 
 21 
 22 #----- MySQL 5.x
 23 # Only InnoDB storage engine is supported (not myISAM).
 24 # Only the bundled driver is supported. It can not be changed.
 25 sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8&amp;rewriteBatchedStatements=true&amp;useConfigs=maxPerformance

Now, go to your top level build.gradle and add this configure buildscript.dependencies to include this line:

buildscript {
    dependencies {
       classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:1.2"
    }
}

Go to your project build.gradle and setup it as follows with top level entries:

apply plugin: 'org.sonarqube'
sonarqube {
    properties {
        property "sonar.projectName", "PROJECT_NAME"
        property "sonar.projectKey", "PROJECT_KEY"
        property "sonar.language", "java"
        property "sonar.projectVersion", "1.1"
        property "sonar.sources", "src/main/"
        property "sonar.tests", "src/androidTest/"
        property "sonar.scm.provider", "git"
 
        property "sonar.host.url", "http://localhost:9000"
 
        property "sonar.jdbc.driverClassName", "com.mysql.jdbc.Driver"
    }
}

To test if your project is setup correctly and start first analysis, you just run gradle with task `sonarqube`:

➜  PROJECT git:(master) ✗ ./gradlew sonarqube
Incremental java compilation is an incubating feature.
:PROJECT:sonarqube
Bytecode of dependencies was not provided for analysis of source files, you might end up with less precise results. Bytecode can be provided using sonar.java.libraries property
Bytecode of dependencies was not provided for analysis of test files, you might end up with less precise results. Bytecode can be provided using sonar.java.test.libraries property
Java bytecode has not been made available to the analyzer. The org.sonar.java.bytecode.visitor.DependenciesVisitor@1beb7984, org.sonar.java.checks.unused.UnusedPrivateMethodCheck@2e1003d9 are disabled.
 
BUILD SUCCESSFUL
 
Total time: 58.183 secs

sonarqube board

[Total: 0    Average: 0/5]