Skip to content

UnusedMethod checker crashes on JDK 17 #2926

Closed

Description

@TimvdLippe

Yesterday I received the Dependabot PR for ErrorProne 2.11.0 on Mockito (mockito/mockito#2553) and I have been working on integrating the change. Besides some small breaking changes, everything appears to work fine on JDK 11, but it fails on JDK 17 with the following exception:

Details
     error-prone version: 2.11.0
     BugPattern: UnusedMethod
     Stack Trace:
     java.lang.NoClassDefFoundError: com/sun/tools/javac/util/Filter
  	at com.google.errorprone.bugpatterns.UnusedMethod.fixConstructors(UnusedMethod.java:357)
  	at com.google.errorprone.bugpatterns.UnusedMethod.matchCompilationUnit(UnusedMethod.java:331)
  	at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:449)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:555)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:150)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:614)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:60)
  	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:152)
  	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:1394)
  	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1341)
  	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:933)
  	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:89)
  	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:54)
  	at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:39)
  	at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerWorkAction.execute(AbstractDaemonCompiler.java:135)
  	at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
  	at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:49)
  	at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:43)
  	at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
  	at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:43)
  	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:85)
  	at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:55)
  	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.run(WorkerAction.java:135)
  	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  	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)
> Task :compileTestJava
  	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.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
  	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
  	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
  	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:61)
  	at java.base/java.lang.Thread.run(Thread.java:833)
  Caused by: java.lang.ClassNotFoundException: com.sun.tools.javac.util.Filter
  	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
  	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
  	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)

Activity

  1. tbroyer commented on Jan 27, 2022

    @tbroyer
    Contributor

    At first glance, looks like these should use ASTHelper.scope(symbol.members()).getSymbols(…):

    int constructorCount = size(symbol.members().getSymbols(Symbol::isConstructor));
    int finalFields =
    size(
    symbol
    .members()
    .getSymbols(s -> s.getKind().equals(FIELD) && s.getModifiers().contains(FINAL)));

  2. cushon commented on Jan 27, 2022

    @cushon
    Collaborator

    I think this was a regression in 5e6691c, and I guess we aren't running tests that exercise that line on 17

  3. tbroyer commented on Jan 27, 2022

    @tbroyer
    Contributor

    The tests on GitHub run the whole build with the same JDK, so this line will correctly be compiled against the Predicate<…> version of the the method with JDK 17, and the Filter version with JDK 11, so it then runs without problem if/when exercised in tests.
    Ideally, compilation would always be done with the same JDK (currently JDK 11 apparently), and tests with a selected JDK. With Maven this could be done with toolchains, or by re-running the build with a different JDK and skipping compilation with -Dmaven.main.skip to reuse the classes from a previous build (or, of course, splitting tests into a separate Maven project so one run can mvn install and the other with a different JDK can only run the test project and consume artifacts from the local repository).
    Alternatively, there could probably be a static analysis check (*cough* ErrorProne *cough*) to fail the build if methods that have a specific ASTHelper version are called outside ASTHelper.

  4. remal commented on Feb 14, 2022

    @remal

    Guys, can the fix be released?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions