Over a million developers have joined DZone.

A SonarQube Plugin for Kotlin: Creating the Plugin

DZone's Guide to

A SonarQube Plugin for Kotlin: Creating the Plugin

After parsing the code and creating the checks, this series on SonarQube plugins goes into coding up an actual plugin for custom-developed violations.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

This is the third post in a series about creating a SonarQube plugin for the Kotlin language:

  • The first post was about creating the parsing code itself.
  • The second post detailed how to use the parsing code to check for two rules.

In this final post, we will be creating the plugin proper using the code of the 2 previous posts.

The Sonar Model

The Sonar model is based on the following abstractions:


Entry-point for plugins to inject extensions into SonarQube

A plugin points to the other abstraction instances to make the SonarQube platform load them


Pretty self-explanatory. Represents a language: Java, C#, Kotlin, etc.


Define a profile which is automatically registered during sonar startup

A profile is a mutable set of fully configured rules. While not strictly necessary, having a Sonar profile pre-registered allows users to analyze their code without further configuration. Every language plugin offered by Sonar has at least one profile attached.


Defines some coding rules of the same repository

Defines an immutable set of rule definitions into a repository. While a rule definition defines available parameters, default severity, etc. the rule (from the profile) defines the exact value for parameters, a specific severity, etc. In short, the rule implements the role definition.


A sensor is invoked once for each module of a project, starting from leaf modules. The sensor can parse a flat file, connect to a web server... Sensors are used to add measure and issues at file level.

The sensor is the entry-point where the magic happens.

Starting to Code the Plugin

Every abstraction above needs a concrete subclass. Note that the API classes themselves are all fairly decoupled. It’s the role of the Plugin child class to bind them together.

class KotlinPlugin : Plugin {

    override fun define(context: Context) {

Most of the code is mainly boilerplate, but for ANTLR code.

Wiring the ANTLR Parsing Code

On one hand, the parsing code is based on generated listeners. On the other hand, the sensor is the entry-point to the SonarQube parsing. There’s a need for a bridge between the two.

In the first article, we used an existing grammar for Kotlin to generate parsing code. SonarQube provides its own lexer/parser generating tool (SonarSource Language Recognizer). A sizeable part of the plugin API is based on it. Describing the grammar is no small feat for any real-life language, so I preferred to design my own adapter code instead.


Subclass of the generated ANTLR KotlinParserBaseListener. It has an attribute to store violations, and a method to add such a violation.


The violation only contains the line number, as the rest of the required information will be stored into a KotlinCheck instance.


Abstract class that wraps an AbstractKotlinParserListener. Defines what constitutes a violation. It handles the ANTLR boilerplate code itself.

This can be represented as the following:

The Sensor

The general pseudo-code should look something akin to:

FOR EACH source file
    FOR EACH rule
        Check for violation of the rule
        FOR EACH violation
            Call the SonarQube REST API to create a violation in the datastore

This translates as:

class KotlinSensor(private val fs: FileSystem) : Sensor {

    val sources: Iterable<InputFile>
        get() = fs.inputFiles(MAIN)

    override fun execute(context: SensorContext) {
        sources.forEach { inputFile: InputFile ->
            KotlinChecks.checks.forEach { check ->
                val violations = check.violations(inputFile.file())
                violations.forEach { (lineNumber) ->
                    with(context.newIssue().forRule(check.ruleKey())) {
                        val location = newLocation().apply {

Finally, the Run

Let’s create a dummy Maven project with two classes, Test1 and Test2 in one Test.kt file, with the same code as last week. Running mvn sonar:sonar yields the following output:

Image title

Et voilà, our first SonarQube plugin for Kotlin, checking for our custom-developed violations.

Of course, it has (a lot of) room for improvements:

  • Rules need to be activated through the GUI: I couldn’t find how to do it programmatically
  • Adding new rules needs updates to the plugin. Rules in third-party plugins are not added automatically, as could be the case for standard SonarQube plugins.
  • So far, code located outside of classes seems not to be parsed.
  • The walk through the parse tree is executed for every check. An obvious performance gain would be to walk only once and do every check from there.
  • A lof of the above improvements could be achieved by replacing ANTLR’s grammar with Sonar’s internal SSLR
  • No tests…

That still makes the project a nice starting point for a full-fledged Kotlin plugin. Pull requests are welcome!

The complete source code for this post can be found on GitHub in Maven format.

To Go Further

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

sonarqube ,kotlin ,plugin development ,java ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}