Missing classes of Sonar-Plugin-Java

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]]

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

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

1 Like

Hi,
I have stumbled upon the same issue

[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar (default-cli) on project word-count: Execution default-cli of goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar failed: A required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar: org/sonar/java/model/expression/AssignmentExpressionTreeImpl

[ERROR] -----------------------------------------------------

[ERROR] realm = plugin>org.codehaus.mojo:sonar-maven-plugin:3.6.0.1398

[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy

[ERROR] urls[0] = file:/Users/ksharma/.m2/repository/org/sonarsource/scanner/maven/sonar-maven-plugin/3.6.0.1398/sonar-maven-plugin-3.6.0.1398.jar

[ERROR] urls[1] = file:/Users/ksharma/.m2/repository/org/sonatype/plexus/plexus-sec-dispatcher/1.4/plexus-sec-dispatcher-1.4.jar

[ERROR] urls[2] = file:/Users/ksharma/.m2/repository/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar

[ERROR] urls[3] = file:/Users/ksharma/.m2/repository/org/codehaus/plexus/plexus-utils/3.0.22/plexus-utils-3.0.22.jar

[ERROR] urls[4] = file:/Users/ksharma/.m2/repository/org/sonarsource/scanner/api/sonar-scanner-api/2.12.0.1661/sonar-scanner-api-2.12.0.1661.jar

[ERROR] urls[5] = file:/Users/ksharma/.m2/repository/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] -----------------------------------------------------: org.sonar.java.model.expression.AssignmentExpressionTreeImpl

[ERROR] -> [Help 1]
toJsonArray

And I am importing these packages from org.sonar.java.model.expression

import org.sonar.java.model.expression.AssignmentExpressionTreeImpl;
import org.sonar.java.model.expression.LiteralTreeImpl;
import org.sonar.java.model.expression.MemberSelectExpressionTreeImpl;
import org.sonar.java.model.expression.MethodInvocationTreeImpl;

Anywork arounds for this?

Hello,

For the exact same reason as explained before, the only valid workaround is to NOT use this implementation classes. You are not supposed to use them.

Test if a tree is of an expected Kind, with Tree.is(Tree.Kind ...), then cast with the corresponding interface.

Regards,
Michael

3 posts were split to a new topic: JavaParser of SonarJava can not be used independently

Sorry for the late reply, but yes i did the same and it worked