Analyze Code Quality Of Java Application Using SonarQube

Table of Contents

Introduction

This tutorial will show you how to analyze code quality of Java applications using SonarQube.

Maintaining the quality of code is an important part of the application and it is required to find out any bugs, issues in the developed code so that you can remove any kind of vulnerabilities from the application before moving to the production.

SonarQube provides the capability to not only show health of an application but also to highlight issues newly introduced. With a Quality Gate in place, you can fix the leak and therefore improve code quality mechanically.

In this example, I will first create a simple Java project (you can create any Java based application – spring, jsf, struts or any Java based application).

Then I will use two different configurations – maven and gradle, for maintaining code quality using SonarQube. Once I configure the SonarQube and run the simple maven or gradle command then the project or application will automatically be appeared in the SonarQube dashboard.

In the dashboard you can analyze the code smells, bugs or any other vulnerabilities in the application and fix accordingly.

Prerequisites

Eclipse or any java based IDE, Java at least 11, SonarQube 8.4.0/9.4.0, Gradle 6.5.1/7.4.2, Maven 3.6.3

Project Setup

I am creating gradle based project here. If you want you can use maven based project also. I will tell you also how to configure sonar for maven based project.

Use below build.gradle script for gradle based project:

plugins {
    id 'java-library'
    id 'org.sonarqube' version "3.0"
}

test {
    ignoreFailures = true
}

sonarqube {
    properties {
        property "sonar.projectName", "${project.name}"
        property "sonar.projectKey", "${project.group}:${project.name}"
    }
}

sourceCompatibility = 12
targetCompatibility = 12

repositories {
    jcenter()
}

dependencies {
	testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
	testImplementation 'org.junit.platform:junit-platform-engine:1.6.2'
}

In the above gradle build file you see that I have used the plugin for using the SonarQube. I have also mentioned the project name and project key for appearing in the SonarQube dashboard.

I have used below instruction in the build file to avoid build failing in case junit tests are failed test { ignoreFailures = true }.

Gradle command to build the application gradlew sonarqube.

If you are using gradle version 7.x then you can use the following build.script:

buildscript {
  	repositories {
    	mavenCentral()
  	}
 
  	dependencies {
    	classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3"
  	}
}

plugins {
    id 'java-library'
    id 'org.sonarqube' version "3.3"
}

test {
    ignoreFailures = true
}

sonarqube {
    properties {
	property "sonar.host.url", "http://localhost:9000"
        property "sonar.projectName", "${project.name}"
        property "sonar.projectKey", "${project.group}:${project.name}"
	property "sonar.login", "4b0f11b3e2ef5aa4b62144899af888baa85ee524"
    }
}

sourceCompatibility = 12
targetCompatibility = 12

repositories {
    jcenter()
}

dependencies {
	testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
	testImplementation 'org.junit.platform:junit-platform-engine:1.6.2'
}

In the above build script I have used sonar.login property for authentication purpose which is required in Sonar Qube 9.x version. I will tell you later how to generate token key for the this property.

For maven based configuration then you can use the below pom.xml file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.roytuts</groupId>
	<artifactId>java-code-quality-sonarqube</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>12</java.version>
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.junit.platform</groupId>
			<artifactId>junit-platform-engine</artifactId>
			<version>1.6.2</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-engine</artifactId>
			<version>5.5.2</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.sonarsource.scanner.maven</groupId>
				<artifactId>sonar-maven-plugin</artifactId>
				<version>3.7.0.1746</version>
			</plugin>
		</plugins>
	</build>
</project>

You see in the above pom.xml file that there is no special configuration for SonarQube.

Maven command to build  the application mvn sonar:sonar.

SonarQube Configuration

I am working on Windows environment with SonarQube.

  • Download SonarQube from https://www.sonarqube.org/
  • Install SonarQube. Simply unzip the zip folder to any drive.
  • Open command prompt and navigate to the directory <physical drive>:\sonarqube-8.4.0.35506\bin\windows-x86-64
  • Now execute the batch file StartSonar.bat
  • Wait for few minutes to start-up the SonarQube until you see something like below in the console:
jvm 1    | INFO  app[][o.s.a.SchedulerImpl] Process[ce] is up
jvm 1    | INFO  app[][o.s.a.SchedulerImpl] SonarQube is up
  • Now hit the URL http://localhost:9000/ in the browser. You will see no project in the dashboard:
sonar java code quality
  • Now build the application using either gradle or maven command
  • Now refresh the SonarQube dashboard
  • You will find your Java application as shown below in the image:
sonar java code quality
  • Clicking on the project link you will see all details
sonar java code quality

Remember: If you are using SonarQube version 9.4.0 then you need to use credentials to enter the dashboard. The default credentials are admin/admin. You will also get the password update page once you enter the default credentials.

sonar qube code quality

As the authentication required for the Sonar version 9.x, you need to generate the token value which can be used for sonar.login property as shown in the build.gradle script file earlier.

To generate token key go to the loggen in user’s avatar (icon) on the top right and click on My Account. Next click on Security tab and you will find the token generation page. You can enter the Token Name and click on Generate button to generate the token. For, example, I have input mytoken as the Token Name in the input box. Finally, copy the generated token value and set it to the sonar.login property section in build.gradle script.

sonarqube code quality

Note that if you do not authorize the user, you won’t be able to scan the project through gradle script in Sonar dashboard and you will see the following error while you are running the build using the command gradlew sonarqube.

> Error creating bean with name 'org.sonarsource.scanner.api.internal.IsolatedClassloader@25b4b9c2-org.sonar.scanner.bootstrap.ScannerPluginRepository': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.sonarsource.scanner.api.internal.IsolatedClassloader@25b4b9c2-org.sonar.scanner.bootstrap.ScannerPluginInstaller': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.sonarsource.scanner.api.internal.IsolatedClassloader@25b4b9c2-org.sonar.scanner.bootstrap.PluginFiles': Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'GlobalConfiguration' defined in org.sonar.scanner.bootstrap.GlobalConfigurationProvider: Unsatisfied dependency expressed through method 'provide' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'GlobalServerSettings' defined in org.sonar.scanner.bootstrap.GlobalServerSettingsProvider: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.sonar.scanner.bootstrap.GlobalServerSettings]: Factory method 'provide' threw exception; nested exception is Not authorized. Please check the properties sonar.login and sonar.password.

That’s all about how to check code quality of your Java based project using sonar qube.

Known Issue

If you see error similar to “SonarQube requires Java 11 to run“, then you can edit the file sonarqube-8.4.0.35506\wrapper.conf and replace wrapper.java.command=java by wrapper.java.command=C:\Java\jdk-12.0.2\bin\java.

Remember to change C:\Java\jdk-12.0.2\bin\java with your system’s Java path.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *