Missing classes of Sonar-Plugin-Java

java
sonarqube
custom_rules

(Hugo Marello) #1

Hello everyone,

I’m having troubles implementing my plugin with custom rules for Java. I’ve implemented and tested some rules locally using SonarQube custom rules example project. It runs smoothly locally, but when trying to analyze a project I get a class not found for org.sonar.java.PackageUtils.class.

My custom plugin has the provided dependency sonar-java-plugin-5.9.2.16552.jar, and SonarQube server has the same version plugin. I’m running the maven scanner with mvn clean install sonar:sonar.

SonarQube version at 7.3 community edition.

Thanks for the help in advance.

Here is my 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>***</groupId>
	<artifactId>***</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>sonar-plugin</packaging>

	<name>***</name>
	<description>****</description>

	<properties>
		<sslr.version>1.21</sslr.version>
		<gson.version>2.6.2</gson.version>
		<sonar.version>7.3</sonar.version>
		<sonarjava.version>5.9.2.16552</sonarjava.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.sonarsource.sonarqube</groupId>
			<artifactId>sonar-plugin-api</artifactId>
			<version>${sonar.version}</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.sonarsource.java</groupId>
			<artifactId>sonar-java-plugin</artifactId>
			<type>sonar-plugin</type>
			<version>${sonarjava.version}</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.sonarsource.sslr-squid-bridge</groupId>
			<artifactId>sslr-squid-bridge</artifactId>
			<version>2.6.1</version>
			<exclusions>
				<exclusion>
					<groupId>org.codehaus.sonar.sslr</groupId>
					<artifactId>sslr-core</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.codehaus.sonar</groupId>
					<artifactId>sonar-plugin-api</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.codehaus.sonar.sslr</groupId>
					<artifactId>sslr-xpath</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>jcl-over-slf4j</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<dependency>
			<groupId>org.sonarsource.java</groupId>
			<artifactId>java-checks-testkit</artifactId>
			<version>${sonarjava.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>${gson.version}</version>
		</dependency>

		<dependency>
			<groupId>org.sonarsource.sslr</groupId>
			<artifactId>sslr-testing-harness</artifactId>
			<version>${sslr.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>

		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>19.0</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.6.2</version>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.assertj</groupId>
			<artifactId>assertj-core</artifactId>
			<version>3.6.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>0.9.30</version>
			<scope>test</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>
						<pluginKey>***</pluginKey>
						<pluginName>***</pluginName>
						<pluginClass>***</pluginClass>
						<sonarLintSupported>true</sonarLintSupported>
						<sonarQubeMinVersion>6.7</sonarQubeMinVersion>
					</configuration>
				</plugin>

				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.6.0</version>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
					</configuration>
				</plugin>

				<!-- only required to run UT - these are UT dependencies -->
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-dependency-plugin</artifactId>
					<version>2.10</version>
					<executions>
						<execution>
							<id>copy</id>
							<phase>test-compile</phase>
							<goals>
								<goal>copy</goal>
							</goals>
							<configuration>
								<artifactItems>
									<artifactItem>
										<groupId>org.apache.commons</groupId>
										<artifactId>commons-collections4</artifactId>
										<version>4.0</version>
										<type>jar</type>
									</artifactItem>
									<artifactItem>
										<groupId>javax</groupId>
										<artifactId>javaee-api</artifactId>
										<version>6.0</version>
									</artifactItem>
									<artifactItem>
										<groupId>org.springframework</groupId>
										<artifactId>spring-webmvc</artifactId>
										<version>4.3.3.RELEASE</version>
									</artifactItem>
									<artifactItem>
										<groupId>org.springframework</groupId>
										<artifactId>spring-webmvc</artifactId>
										<version>4.3.3.RELEASE</version>
									</artifactItem>
									<artifactItem>
										<groupId>org.springframework</groupId>
										<artifactId>spring-web</artifactId>
										<version>4.3.3.RELEASE</version>
									</artifactItem>
									<artifactItem>
										<groupId>org.springframework</groupId>
										<artifactId>spring-context</artifactId>
										<version>4.3.3.RELEASE</version>
									</artifactItem>
								</artifactItems>
								<outputDirectory>${project.build.directory}/test-jars</outputDirectory>
							</configuration>
						</execution>
					</executions>
				</plugin>
			</plugins>
	</build>

</project>

here is the mvn sonar:sonar log:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.005 s
[INFO] Finished at: 2019-02-15T16:01:41-02:00
[INFO] Final Memory: 36M/1247M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254:sonar (default-cli) on project ***-parent: Execution default-cli of goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254:sonar failed: A required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254:sonar: org/sonar/java/model/PackageUtils
[ERROR] -----------------------------------------------------
[ERROR] realm =    plugin>org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/usr/local/***/m2/org/sonarsource/scanner/maven/sonar-maven-plugin/3.5.0.1254/sonar-maven-plugin-3.5.0.1254.jar
[ERROR] urls[1] = file:/usr/local/***/m2/org/sonatype/plexus/plexus-sec-dispatcher/1.4/plexus-sec-dispatcher-1.4.jar
[ERROR] urls[2] = file:/usr/local/***/m2/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
[ERROR] urls[3] = file:/usr/local/***/m2/org/codehaus/plexus/plexus-utils/3.0.22/plexus-utils-3.0.22.jar
[ERROR] urls[4] = file:/usr/local/***/m2/org/sonarsource/scanner/api/sonar-scanner-api/2.10.0.1189/sonar-scanner-api-2.10.0.1189.jar
[ERROR] urls[5] = file:/usr/local/***/m2/commons-lang/commons-lang/2.6/commons-lang-2.6.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import  from realm ClassRealm[maven.api, parent: null]]
[ERROR] 
[ERROR] -----------------------------------------------------
[ERROR] : org.sonar.java.model.PackageUtils
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254:sonar (default-cli) on project ***-parent: Execution default-cli of goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254:sonar failed: A required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254:sonar: org/sonar/java/model/PackageUtils
-----------------------------------------------------
realm =    plugin>org.sonarsource.scanner.maven:sonar-maven-plugin:3.5.0.1254
strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
urls[0] = file:/usr/local/***/m2/org/sonarsource/scanner/maven/sonar-maven-plugin/3.5.0.1254/sonar-maven-plugin-3.5.0.1254.jar
urls[1] = file:/usr/local/***/m2/org/sonatype/plexus/plexus-sec-dispatcher/1.4/plexus-sec-dispatcher-1.4.jar
urls[2] = file:/usr/local/***/m2/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
urls[3] = file:/usr/local/***/m2/org/codehaus/plexus/plexus-utils/3.0.22/plexus-utils-3.0.22.jar
urls[4] = file:/usr/local/***/m2/org/sonarsource/scanner/api/sonar-scanner-api/2.10.0.1189/sonar-scanner-api-2.10.0.1189.jar
urls[5] = file:/usr/local/***/m2/commons-lang/commons-lang/2.6/commons-lang-2.6.jar
Number of foreign imports: 1
import: Entry[import  from realm ClassRealm[maven.api, parent: null]]

-----------------------------------------------------

(Michael Gumowski) #2

Hello @Hugo_Marello,

The class PackageUtils.java is not part of the SonarJava API, and therefore not exposed/available at runtime. Unfortunately, this does not prevent custom rules unit tests to pass when building the custom plugin. As you mentioned, using such classes won’t have the same behavior once installed on a SonarQube instance, and will make any analysis fail.

Can you check that you are not relying on it in your rules?

  • If it’s the case, I would encourage you to duplicate that code (I know…) directly into your custom plugin.
  • If it’s not, then we will need to dig a bit more to understand the issue.

Eventually, we may think about moving some of these utility classes related to the java AST into the API (I’m thinking about the ExpressionUtils, LiteralUtils, ModifiersUtils and PackageUtils, which are used by our rules, but not available in API).

Hope this helps,
Michael