Skip to end of metadata
Go to start of metadata

Prerequisites

To build a plugin, you need Java 8 and Maven 3.1 (or greater). SonarQube 5.6 does not support plugins compiled for Java 7.

Gradle can also be used thanks to https://github.com/iwarapter/gradle-sonar-packaging-plugin. Note that this Gradle plugin is not officially supported by SonarSource.

Create a Maven Project

The recommended way is to duplicate the example located in the GitHub repository: https://github.com/SonarSource/sonar-custom-plugin-example.

If you want to start the project from scratch, then simply use the following template for Maven pom.xml:

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>YOUR_GROUP_ID</groupId>
  <!-- it's recommended to follow the pattern "sonar-{key}-plugin", for example "sonar-php-plugin" -->
  <artifactId>YOUR_ARTIFACT_ID</artifactId>
  <version>YOUR_VERSION</version>
 
  <!-- this is important for sonar-packaging-maven-plugin -->
  <packaging>sonar-plugin</packaging>

  <dependencies>
    <dependency>
      <groupId>org.sonarsource.sonarqube</groupId>
      <artifactId>sonar-plugin-api</artifactId>
      <!-- minimal version of SonarQube to support. Note that the groupId was "org.codehaus.sonar" before version 5.2 -->
      <version>5.6</version>
      <!-- mandatory scope -->
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
        <artifactId>sonar-packaging-maven-plugin</artifactId>
        <version>1.17</version>
        <extensions>true</extensions>
        <configuration>
          <!-- the entry-point class that extends org.sonar.api.SonarPlugin -->
          <pluginClass>com.mycompany.sonar.reference.ExamplePlugin</pluginClass>
          
          <!-- advanced properties can be set here. See paragraph "Advanced Build Properties". -->
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Build

Simply execute the command from the root directory of the project:

mvn clean package

The plugin JAR file is generated in the directory target/.

Deploy

"Cold" Deploy

The standard way is to install the plugin for regular users is to: copy the JAR artifact, located in the target/ directory  to the  extensions/plugins/ directory of your SonarQube installation then start server. The file logs/sonar.log will then contain a log line similar to:

Deploy plugin Example Plugin / 0.1-SNAPSHOT

Scanner extensions such as sensors are immediately retrieved and loaded when scanning source code. 

"Hot" Deploy

Deprecated since SonarQube 6.x

This only applies to SonarQube versions up to LTS v5.6.x - SONAR-9263 - Getting issue details... STATUS

Plugins can be reloaded at runtime by the SonarQube server without requiring a full restart. That saves some precious seconds. This mode is enabled only for development, as it may have memory leaks after a few hot deployments.

  1. add the property sonar.web.dev=true to conf/sonar.properties
  2. restart the server
  3. build and deploy plugin with:

    # property sonarUrl is optional. Default value is http://localhost:9000
    mvn package org.codehaus.sonar:sonar-dev-maven-plugin::upload -DsonarHome=/path/to/server/home -DsonarUrl=http://localhost:8080

Debug

Debugging Web Server Extensions

  1. Edit conf/sonar.properties and set:

    sonar.web.javaAdditionalOpts=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000
  2. Install your plugin by copying its JAR file to extensions/plugins
  3. Start the server. The log "Listening for transport dt_socket at address: 5005" is displayed in logs/sonar.log.
  4. Attach your IDE to the debug process (listening on port 8000 in the example)

Debugging Compute Engine Extensions

Same procedure as for web server extensions (see previous paragraph), but with the property:

sonar.ce.javaAdditionalOpts=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000

Debugging Scanner Extensions

SonarQube Scanner
export SONAR_SCANNER_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"
cd /path/to/project
sonar-scanner 

When using the Scanner for Maven, then simply execute:

SonarQube Scanner for Maven
cd /path/to/project
mvnDebug sonar:sonar
# debug port is 8000

Advanced Build Properties

Plugin properties are defined in the file META-INF/MANIFEST.MF of the plugin .jar file.

Most of them are defined through the <configuration> section of the sonar-packaging-maven-plugin (see JIRA tickets). Some are taken from standard pom nodes Effective values are listed at the end of the build log:

[INFO] --- sonar-packaging-maven-plugin:1.15:sonar-plugin (default-sonar-plugin) @ sonar-widget-lab-plugin ---
[INFO] -------------------------------------------------------
[INFO] Plugin definition in update center
[INFO]     Key: widgetlab
[INFO]     Name: Widget Lab
[INFO]     Description: Additional widgets
[INFO]     Version: 1.9-SNAPSHOT
[INFO]     Entry-point Class: org.codehaus.sonar.plugins.widgetlab.WidgetLabPlugin
[INFO]     Required Plugins: 
[INFO]     Use Child-first ClassLoader: false
[INFO]     Base Plugin: 
[INFO]     Homepage URL: https://redirect.sonarsource.com/plugins/widgetlab.html
[INFO]     Minimal SonarQube Version: 4.5.1
[INFO]     Licensing: GNU LGPL 3
[INFO]     Organization: Shaw Industries
[INFO]     Organization URL: http://shawfloors.com
[INFO]     Terms and Conditions: 
[INFO]     Issue Tracker URL: http://jira.codehaus.org/browse/SONARWIDLB
[INFO]     Build date: 2015-12-15T18:28:54+0100
[INFO]     Sources URL: https://github.com/SonarCommunity/sonar-widget-lab
[INFO]     Developers: G. Ann Campbell,Patroklos Papapetrou
[INFO] -------------------------------------------------------
[INFO] Building jar: /dev/sonar-widget-lab/target/sonar-widget-lab-plugin-1.9-SNAPSHOT.jar 

Supported standard pom node properties:

Maven PropertyManifest KeyNotesMaven Defaults
versionPlugin-Version(required) Plugin version as displayed in page "Update Center".${project.version}
-Sonar-Version(required) Minimal version of supported SonarQube at runtime. For example if value is 5.2, then deploying the plugin on versions 5.1 and lower will fail.
Default value is given by the version of sonar-plugin-api dependency. It can be overridden with the Maven property sonarQubeMinVersion (since sonar-packaging-maven-plugin 1.16). That allows in some cases to use new features of recent API and to still be compatible at runtime with older versions of SonarQube.
Version of dependency sonar-plugin-api
licensePlugin-LicensePlugin license as displayed in page "Update Center"Names of ${project.licenses}
developersPlugin-DevelopersList of developers displayed in page "Update Center"Names of ${project.developers}

 

Supported <configuration> properties:

Maven PropertyManifest KeyNotesMaven Defaults
pluginKeyPlugin-Key(required) Contains only letters/digits and is unique among all plugins.
Examples: groovy, widgetlab

Constructed from ${project.artifactId}.

Given an artifactId of: sonar-widget-lab-plugin
Your pluginKey will be: widgetlab

pluginClassPlugin-Class(required) Name of the entry-point class that extends org.sonar.api.SonarPlugin
Example: org.codehaus.sonar.plugins.widgetlab.WidgetLabPlugin
 
pluginNamePlugin-Name(required) Displayed in the page "Update Center".${project.name}
pluginDescriptionPlugin-DescriptionDisplayed in the page "Update Center".${project.description}

pluginUrl

Plugin-Homepage

Homepage of website, for example https://github.com/SonarQubeCommunity/sonar-widget-lab

${project.url}

pluginIssueTrackerUrl

Plugin-IssueTrackerUrl

Example: https://github.com/SonarQubeCommunity/sonar-widget-lab/issues

${project.issueManagement.url}

pluginTermsConditionsUrl

Plugin-TermsConditionsUrl

Example: https://dist.sonarsource.com/SonarSource_Terms_And_Conditions.pdf

Users must read this document when installing the plugin from Update Center.

${sonar.pluginTermsConditionsUrl}

useChildFirstClassLoader

Plugin-ChildFirstClassLoader

Each plugin is executed in an isolated classloader, which inherits a shared classloader that contains API and some other classes. By default the loading strategy of classes is parent-first (look up in shared classloader then in plugin classloader). If the property is true, then the strategy is child-first.
This property is mainly used when building plugin against API < 5.2, as the shared classloader contained many 3rd party libraries (guava 10, commons-lang, ...)

false

basePlugin

Plugin-Base

If specified, then the plugin is executed in the same classloader as basePlugin. That is mainly used when extending rules of a rule engine plugin.

 

pluginSourcesUrl
Plugin-SourcesUrlURL of SCM repository for open-source plugins. Displayed in page "Update Center"${project.scm.url}
pluginOrganizationNamePlugin-OrganizationOrganization which develops the plugin, displayed in the page "Update Center"${project.organization.name}
pluginOrganizationUrlPlugin-OrganizationUrlURL of the organization, displayed in the page "Update Center"${project.organization.url}
sonarLintSupportedSonarLint-SupportedWhether the (language) plugin supports SonarLint or not 
pluginDisplayVersionPlugin-Display-VersionThe version as displayed in SonarQube administration console. By default it's the raw version, for example "1.2", but can be overridden to "1.2 (build 12345)" for instance.
Supported in sonar-packaging-maven-plugin 1.18.0.372. 
${project.version}

 

The Maven sonar-packaging-maven-plugin supports also these properties:

addMavenDescriptor

Copy pom file inside the directory META-INF of generated JAR file ?
Supported values: true | false

${sonar.addMavenDescriptor}. Default is true.

skipDependenciesPackaging

Do not copy Maven dependencies into JAR file.

${sonar.skipDependenciesPackaging}. Default is false.

Other Manifest Fields

FieldDescription
Implementation-BuildIdentifier of build or commit, for example the Git sha1 "94638028f0099de59f769cdca776e506684235d6". It is displayed for debugging purpose in logs when SonarQube server starts.

 

 

  • No labels