Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.ClassCastException: class com.sun.tools.javac.tree.JCTree$JCLiteral cannot be cast to class com.sun.source.tree.IdentifierTree #831

Closed
bdeneuter opened this issue Sep 12, 2023 · 8 comments · Fixed by #839

Comments

@bdeneuter
Copy link

With version 0.10.14 we receive a ClassCastException on a switch statement. With the previous version 0.10.13 NullAway validated correctly.

The JDK that we are using is JDK 20 (Temurin).

This is the piece of code that gives a problem:

static <T extends Metric<?>> GroupByQuery<T> toGroupByQueryWithExtractor(
      GroupBy groupBy, GroupByResultExtractor<T> extractor) {
    return switch (groupBy) {
      case OWNER -> new GroupByOwnerQuery<>(extractor);
      case CHANNEL -> new GroupByChannelQuery<>(extractor);
      case TOPIC -> new GroupByTopicQuery<>(extractor);
      case TEAM -> new GroupByTeamQuery<>(extractor);
      case null -> throw new IllegalArgumentException("GroupBy parameter is required");
    };
  }

The error that we get:

return switch (groupBy) {
    ^
     Please report this at https://github.com/google/error-prone/issues/new and include the following:
  
     error-prone version: 2.21.1
     BugPattern: NullAway
     Stack Trace:
     com.google.common.util.concurrent.UncheckedExecutionException: java.lang.ClassCastException: class com.sun.tools.javac.tree.JCTree$JCLiteral cannot be cast to class com.sun.source.tree.IdentifierTree (com.sun.tools.javac.tree.JCTree$JCLiteral and com.sun.source.tree.IdentifierTree are in module jdk.compiler of loader 'app')
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2086)
        at com.google.common.cache.LocalCache.get(LocalCache.java:4012)
        at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4035)
        at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5013)
        at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5020)
        at com.uber.nullaway.dataflow.DataFlow.dataflow(DataFlow.java:154)
        at com.uber.nullaway.dataflow.DataFlow.resultFor(DataFlow.java:290)
        at com.uber.nullaway.dataflow.DataFlow.resultForExpr(DataFlow.java:266)
        at com.uber.nullaway.dataflow.DataFlow.expressionDataflow(DataFlow.java:208)
        at com.uber.nullaway.dataflow.AccessPathNullnessAnalysis.getNullness(AccessPathNullnessAnalysis.java:131)
        at com.uber.nullaway.NullAway.nullnessFromDataflow(NullAway.java:2357)
        at com.uber.nullaway.NullAway.mayBeNullExpr(NullAway.java:2335)
        at com.uber.nullaway.NullAway.checkReturnExpression(NullAway.java:862)
        at com.uber.nullaway.NullAway.matchReturn(NullAway.java:392)
        at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:449)
        at com.google.errorprone.scanner.ErrorProneScanner.visitReturn(ErrorProneScanner.java:816)
        at com.google.errorprone.scanner.ErrorProneScanner.visitReturn(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1737)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:111)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:272)
        at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:520)
        at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1100)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:96)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitMethod(TreeScanner.java:224)
        at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:740)
        at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:944)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:96)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:111)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:119)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitClass(TreeScanner.java:203)
        at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:548)
        at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:851)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:111)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:119)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitCompilationUnit(TreeScanner.java:152)
        at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:560)
        at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:619)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:66)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:58)
        at com.google.errorprone.scanner.ErrorProneScannerTransformer.apply(ErrorProneScannerTransformer.java:43)
        at com.google.errorprone.ErrorProneAnalyzer.finished(ErrorProneAnalyzer.java:156)
        at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:132)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1408)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1355)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:947)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
        at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:92)
        at org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:94)
        at org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57)
        at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:55)
        at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:39)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractIsolatedCompilerWorkerExecutor$CompilerWorkAction.execute(AbstractIsolatedCompilerWorkerExecutor.java:78)
        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
        at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:54)
        at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:48)
        at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
        at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:48)
        at org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:32)
        at org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:22)
        at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:96)
        at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:65)
        at org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:138)
        at org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41)
        at org.gradle.process.internal.worker.request.WorkerAction.lambda$run$0(WorkerAction.java:135)
        at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80)
        at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:127)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:578)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
        at java.base/java.lang.Thread.run(Thread.java:1623)
  Caused by: java.lang.ClassCastException: class com.sun.tools.javac.tree.JCTree$JCLiteral cannot be cast to class com.sun.source.tree.IdentifierTree (com.sun.tools.javac.tree.JCTree$JCLiteral and com.sun.source.tree.IdentifierTree are in module jdk.compiler of loader 'app')
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne$SwitchBuilder.casesAreExhaustive(CFGTranslationPhaseOne.java:2565)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne$SwitchBuilder.build(CFGTranslationPhaseOne.java:2344)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.visitSwitchExpression17(CFGTranslationPhaseOne.java:585)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.scan(CFGTranslationPhaseOne.java:548)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.visitReturn(CFGTranslationPhaseOne.java:3389)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.visitReturn(CFGTranslationPhaseOne.java:201)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1737)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.scan(CFGTranslationPhaseOne.java:556)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.visitBlock(CFGTranslationPhaseOne.java:2211)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.visitBlock(CFGTranslationPhaseOne.java:201)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1100)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.scan(CFGTranslationPhaseOne.java:556)
        at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.process(CFGTranslationPhaseOne.java:455)
        at com.uber.nullaway.dataflow.cfg.NullAwayCFGBuilder.build(NullAwayCFGBuilder.java:78)
        at com.uber.nullaway.dataflow.DataFlow$2.load(DataFlow.java:137)
        at com.uber.nullaway.dataflow.DataFlow$2.load(DataFlow.java:102)
        at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3571)
        at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2313)
        at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2190)
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2080)
        ... 96 more

@msridhar
Copy link
Collaborator

Thanks for the report! This is likely due to updating Checker Dataflow to 3.38.0. Can you confirm that GroupBy is an enum? We'll get this reported upstream.

@bdeneuter
Copy link
Author

I can confirm it is indeed an enum.

public enum GroupBy {
  OWNER,
  CHANNEL,
  TOPIC,
  TEAM
}

@bdeneuter
Copy link
Author

Sorry, I forgot to mention that we use JDK 20 with Preview features enabled

@msridhar
Copy link
Collaborator

Thanks @bdeneuter these features are now stabilized with JDK 21. This issue is being investigated in typetools/checker-framework#6173 and typetools/checker-framework#6174

armughan11 added a commit to armughan11/NullAway that referenced this issue Sep 28, 2023
Added test for null case (covering uber#831) and changed JDK 17 to JDK 21 for unit testing
msridhar added a commit that referenced this issue Sep 28, 2023
Added test for null case in switch statements (covering #831) and
changed JDK 17 to JDK 21 for testing recent language features

---------

Co-authored-by: Manu Sridharan <[email protected]>
msridhar added a commit that referenced this issue Oct 5, 2023
Fixes #831 as Checker Framework dataflow now has support for JDK 21
constructs
@msridhar
Copy link
Collaborator

msridhar commented Oct 5, 2023

@bdeneuter now that we got this crasher fixed is there any way you could try out a snapshot build again to see if there are further NullAway crashes on your codebase?

Also, assuming there are no further crashes, would it be helpful to you if we cut a new release with this fix?

@bdeneuter
Copy link
Author

@msridhar I tested it with the SNAPSHOT version and I don't have any crashes anymore with the service where we had this crash.
It would be nice to have a new release with this fix so we can upgrade this service also to JDK21

@msridhar
Copy link
Collaborator

msridhar commented Oct 5, 2023

Ok thanks for the testing @bdeneuter! We will work on cutting a bug-fix release soon.

@msridhar
Copy link
Collaborator

@bdeneuter version 0.10.15 is out with the fix. Please let us know if you have any issues with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants