java.lang.ClassCastException: org.sonar.java.model.DefaultJavaFileScannerContext cannot be cast to org.sonar.java.model.DefaultJavaFileScannerContext

Sonarqube 8.2:
Hello Team,
I am using sonarquebe 8.2 for wtriting a custom java rule, below is code.

@Rule(key = "CorsEnable")
public class CorsEnableCheck2 extends IssuableSubscriptionVisitor implements EndOfAnalysisCheck {

  private static final String JAVA_CONFIG = "JAVA_CONFIG";
  private final Map<String, List<AnalyzerMessage>> messagesPerPackage = new HashMap<>();

  private static final MethodMatcherCollection ADD_ALLOWED_ORIGIN_MATCHER =
      MethodMatcherCollection.create(
          MethodMatcher.create().typeDefinition("org.springframework.web.cors.CorsConfiguration")
              .name("addAllowedOrigin").withAnyParameters(),
          MethodMatcher.create()
              .typeDefinition("org.springframework.web.servlet.config.annotation.CorsRegistration")
              .name("allowedOrigins").withAnyParameters());

  // @Override
  public List<Kind> nodesToVisit() {
    return Collections.singletonList(Tree.Kind.METHOD);
  }

  // @Override
  public void visitNode(Tree tree) {

    MethodTree methodTree = (MethodTree) tree;
    Symbol.MethodSymbol methodSymbol = methodTree.symbol();

    if (isFilter(methodSymbol)) {
      if (isInvalidFilterBasedConfiguration(methodTree, methodSymbol)) {
        addMessageToMap(JAVA_CONFIG, methodTree.simpleName());
      }
    }

  }

   private void addMessageToMap(String key, IdentifierTree classNameTree) {
    DefaultJavaFileScannerContext defaultContext = (DefaultJavaFileScannerContext) context;
    AnalyzerMessage analyzerMessage =
        defaultContext.createAnalyzerMessage(this, classNameTree, MESSAGE);
    messagesPerPackage.computeIfAbsent(key, k -> new ArrayList<>()).add(analyzerMessage);
  }

  @Override
  public void endOfAnalysis() {
    DefaultJavaFileScannerContext defaultContext = (DefaultJavaFileScannerContext) context;
    messagesPerPackage.get(JAVA_CONFIG).forEach(defaultContext::reportIssue);
    // Do something

  }

}

Here Is the exception stact trace

[ERROR] Unable to run check class org.sonar.samples.java.checks.CorsEnableCheck - CorsEnable on file 'src/main/java/com/example/demo/WebConfig.java', To help improve the SonarSource Java Analyzer, please report this problem to SonarSource: see https://community.sonarsource.com/
java.lang.ClassCastException: org.sonar.java.model.DefaultJavaFileScannerContext cannot be cast to org.sonar.java.model.DefaultJavaFileScannerContext
        at org.sonar.samples.java.checks.CorsEnableCheck.addMessageToMap(CorsEnableCheck.java:175)
        at org.sonar.samples.java.checks.CorsEnableCheck.visitNode(CorsEnableCheck.java:88)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.lambda$visit$6(VisitorsBridge.java:311)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.lambda$forEach$9(VisitorsBridge.java:326)
        at org.sonar.java.model.VisitorsBridge.runScanner(VisitorsBridge.java:189)
        at org.sonar.java.model.VisitorsBridge.access$100(VisitorsBridge.java:66)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.forEach(VisitorsBridge.java:326)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:313)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:297)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:317)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:297)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:317)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:297)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:317)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:297)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:317)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:297)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:317)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:297)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:317)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visitChildren(VisitorsBridge.java:297)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.visit(VisitorsBridge.java:317)
        at org.sonar.java.model.VisitorsBridge$IssuableSubsciptionVisitorsRunner.run(VisitorsBridge.java:288)
        at org.sonar.java.model.VisitorsBridge.visitFile(VisitorsBridge.java:171)
        at org.sonar.java.ast.JavaAstScanner.simpleScan(JavaAstScanner.java:98)
        at org.sonar.java.ast.JavaAstScanner.scan(JavaAstScanner.java:64)
        at org.sonar.java.JavaSquid.scanSources(JavaSquid.java:120)
        at org.sonar.java.JavaSquid.scan(JavaSquid.java:113)
        at org.sonar.plugins.java.JavaSquidSensor.execute(JavaSquidSensor.java:103)
        at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
        at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
        at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
        at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:386)
        at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:382)
        at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:351)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
        at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:141)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
        at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:72)
        at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:66)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at com.sun.proxy.$Proxy28.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
        at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
        at org.sonarsource.scanner.maven.bootstrap.ScannerBootstrapper.execute(ScannerBootstrapper.java:65)
        at org.sonarsource.scanner.maven.SonarQubeMojo.execute(SonarQubeMojo.java:104)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:956)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:192)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)

FYI: I have addded the depdency

org.sonarsource.java
java-frontend
${sonarjava.version}

to fix the MethodMatcherCollection, class not found issue.

Hello,

When working with custom rules, I highly recommend using only what is provided by the public API (org.sonar.plugins.java.api.).
What could go wrong?
In fact, the code you provide is already a perfect example: we reworked MethodMatchers in version 6.3, and removed MethodMatcherCollection. This means that if you use the new version, your custom plugin will not work anymore, and understanding why can be tricky. Of course, public API can also change, but you can expect to be notified if it happens.
The good part is that we reworked MethodMatchers exactly for the purpose of exposing it in the public API, so I would advise you to update to 6.3 (or not use it!).

Now, coming back to your original problem, I would not be surprised if you are facing the same issue as in the post you just linked:

only classes under api packages are provided during analyze time or during rules loading at the server side.

The solutions provided there can probably lead your researches, but be sure to be aware of what it implies to avoid painful hours of debugging in the future!

Best,
Quentin

1 Like

@Quentin, Thanks for the reply, I have upgraded to version 6.3, But still, I am having an issue with EndOfAnalysisCheck, For this, I need to add java-frontend.jar into my classpath otherwise I am getting Class NotFoud Exception, If I add the java-frontend.jar again the same old story I am getting java.lang.ClassCastException: Cannot cast org.sonar.java.model.DefaultJavaFileScannerContext to org.sonar.java.model.DefaultJavaFileScannerContext
Can you please let me know how to work with EndOfAnalysisCheck or is there any equivalent way. I need to check something after the scanning has done, Thank you.

The reason why EndOfAnalysisCheck is not part of the public API is that it is still an experimental feature on our side (hence annotated with @Beta), we did not reach a state where we are satisfied enough to expose it to the public.

Concerning the workaround that you are trying, as explained in my first post, this is not the way it is intended to work, I don’t think I can help here. To my knowledge, there is no official way to obtain such behavior in custom plugins, we take good notes of your request and will be happy to consider it if it happens to be a common request.

Best,
Quentin