Sam Sabah
Sam Sabah

Reputation: 41

mvn sonar:sonar running Error: cannot be cast to org.sonar.java.resolve.JavaSymbol$TypeJavaSymbol

I'm writing a Sonarqube Java custom rule but keep having this error as I try to analyze my code:

"SonarQube is unable to analyze file 'File Path' org.sonar.java.resolve.JavaSymbol$TypeJavaSymbol cannot be cast to org.sonar.java.resolve.JavaSymbol$TypeJavaSymbol"

As you can see the original type and the casted type have the same qualified name. Therefore I assume this can only be a ClassLoader shading issue.

You can find the entire code as open-source here: https://github.com/oasp-forge/sonarqube-devon-plugin (in case you want to check the POM or rule class).

Here is the rule code causing the issue:

package io.oasp.ide.sonarqube.common.impl;

import io.oasp.module.basic.common.api.reflect.OaspPackage;

@Rule(key = "ArchitecturePackageCheck", name = "My Package Check", description = "Verify that the code is following My package conventions.", //
    priority = Priority.MAJOR, tags = { "bug" })
public class ArchitecturePackageCheck extends BaseTreeVisitor implements JavaFileScanner {

  private List<String> issues;

  private String fullyQualifiedName;

  /**
   * The constructor.
   */
  public DevonArchitecturePackageCheck() {
    super();
    this.issues = new ArrayList<>();
  }

  /**
   * @return fullyQualifiedName
   */
  public String getFullyQualifiedName() {

    return this.fullyQualifiedName;
  }

  @Override
  public void scanFile(JavaFileScannerContext context) {

    this.issues.clear();
    scan(context.getTree());
    for (String issue : this.issues) {
      int lineNumber = 1;
      context.addIssue(lineNumber, this, issue);
    }
  }

  @Override
  public void visitIdentifier(IdentifierTree tree) {

    // TODO Auto-generated method stub
    super.visitIdentifier(tree);
  }

  @Override
  public void visitClass(ClassTree tree) {

    this.fullyQualifiedName = ((JavaSymbol.TypeJavaSymbol) tree.symbol()).getFullyQualifiedName();
    String packageName = " ";

    int lastDot = this.fullyQualifiedName.lastIndexOf('.');
    if (lastDot > 0) {
      packageName = this.fullyQualifiedName.substring(0, lastDot);
    }
    if (packageName.isEmpty()) {
      this.issues.add("Invalid Package IS EMPTY!" + packageName + " !");
    } else {
      OaspPackage pkg = OaspPackage.of(packageName);
      if (!pkg.isValid()) {
        this.issues.add("Invalid Package IS VALID" + packageName + " !");
      }
    }
  }

}

Upvotes: 4

Views: 506

Answers (1)

Tibor Blenessy
Tibor Blenessy

Reputation: 4420

Yes this is most likely related to classloader issue, you shouldn't use classes which are not exposed with the public API, i.e. anything outside the package org.sonar.plugins.java.api .

Proper way to get fully qualified name from the ClassTree is to use the Type class which can be accessed from symbol like this

classTree.symbol().type().fullyQualifiedName()

Upvotes: 1

Related Questions