franz9 franz9 - 17 days ago 8
Java Question

ClassCastException in sonarqube custom java check

Hi I'm writing own plugin for sonarqube version 6.1 using checks from java-plugin in version 4.0. To be more specific I'm trying to extend class SubscriptionVisitor to get help in Java file crawling. But I encountered this problem:

Caused by: java.lang.ClassCastException: org.sonar.java.model.declaration.MethodTreeImpl cannot be cast to org.sonar.java.model.JavaTree
at org.sonar.java.ast.visitors.SubscriptionVisitor.visitChildren(SubscriptionVisitor.java:116)
at org.sonar.java.ast.visitors.SubscriptionVisitor.visit(SubscriptionVisitor.java:97)
at org.sonar.java.ast.visitors.SubscriptionVisitor.scanTree(SubscriptionVisitor.java:78)
at main.java.visitors.VariableVisitor.scan(VariableVisitor.java:50)
at main.java.disharmonies.BrainMethod.visitMethod(BrainMethod.java:51)
at org.sonar.java.model.declaration.MethodTreeImpl.accept(MethodTreeImpl.java:218)
at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitClass(BaseTreeVisitor.java:69)
at org.sonar.java.model.declaration.ClassTreeImpl.accept(ClassTreeImpl.java:198)
at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:37)
at org.sonar.plugins.java.api.tree.BaseTreeVisitor.visitCompilationUnit(BaseTreeVisitor.java:55)
at org.sonar.java.model.JavaTree$CompilationUnitTreeImpl.accept(JavaTree.java:156)
at org.sonar.plugins.java.api.tree.BaseTreeVisitor.scan(BaseTreeVisitor.java:43)
at main.java.disharmonies.BrainMethod.scanFile(BrainMethod.java:29)
at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:123)
at org.sonar.java.ast.JavaAstScanner.simpleScan(JavaAstScanner.java:84)


MethodTreeImpl clearly extends the JavaTree class. I assume the problem will be in different classloader.
Can anybody help me please?

Edit

Here is the plugin's 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>

<name>Disharmonies checker</name>
<groupId>tlestyan.thesis</groupId>
<artifactId>disharmonies</artifactId>
<version>0.1</version>
<packaging>sonar-plugin</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sonar.buildVersion>6.1</sonar.buildVersion>
<sonar-java.version>4.0</sonar-java.version>
<jdk.min.version>1.8</jdk.min.version>
</properties>

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

<dependency>
<groupId>org.sonarsource.java</groupId>
<artifactId>java-checks</artifactId>
<version>${sonar-java.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>

<dependency>
<groupId>org.sonarsource.java</groupId>
<artifactId>sonar-java-plugin</artifactId>
<version>${sonar-java.version}</version>
</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.sonarqube</groupId>
<artifactId>sonar-testing-harness</artifactId>
<version>${sonar.buildVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>

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

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>


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

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.2</version>
</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>sonarMetricProject</pluginKey>
<pluginClass>main.java.plugin.Plugin</pluginClass>
<pluginName>SonarQube Disharmonies Plugin</pluginName>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<pluginDescription> Collects disharmonies metrics </pluginDescription>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${jdk.min.version}</source>
<target>${jdk.min.version}</target>

</configuration>
</plugin>
<plugin>
<!-- UTF-8 bundles are not supported by Java, so they must be converted during build -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>native2ascii-maven-plugin</artifactId>
<version>1.0-beta-1</version>
<executions>
<execution>
<goals>
<goal>native2ascii</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.10</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<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>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-dev-maven-plugin</artifactId>
<version>1.8</version>
</plugin>
</plugins>
</build>

</project>

Answer

You should declare dependency on org.sonarsource.java:sonar-java-plugin and its components as provided. This is shown in examples of custom rules. Otherwise they will be packaged into your plugin and that's why same classes are loaded by different ClassLoaders.