I’ve created a sample project available here to demonstrate this problem
- Download the zip 2. Extract 3. ./gradlew build --stacktrace
Heres the output:
:compileJava UP-TO-DATE
:compileGroovy FAILED
FAILURE: Build failed with an exception.
- What went wrong:
Execution failed for task ‘:compileGroovy’.
java.lang.NoSuchMethodError: com.google.common.collect.Queues.newArrayDeque()Ljava/util/ArrayDeque;
- Try:
Run with --info or --debug option to get more log output.
- Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ‘:compileGroovy’.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:305)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:51)
at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
at org.gradle.launcher.Main.doAction(Main.java:33)
at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:127)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:56)
Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodError: com.google.common.collect.Queues.newArrayDeque()Ljava/util/ArrayDeque;
at com.sun.tools.javac.main.Main.compile(Main.java:469)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:132)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:42)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:35)
at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler$2$1.compile(ApiGroovyCompiler.java:112)
at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:122)
at org.gradle.api.internal.tasks.compile.ApiGroovyCompiler.execute(ApiGroovyCompiler.java:47)
at org.gradle.api.internal.tasks.compile.daemon.CompilerDaemonServer.execute(CompilerDaemonServer.java:53)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
Caused by: java.lang.NoSuchMethodError: com.google.common.collect.Queues.newArrayDeque()Ljava/util/ArrayDeque;
at dagger.internal.codegen.InjectBindingRegistry.(InjectBindingRegistry.java:68)
at dagger.internal.codegen.ComponentProcessor.init(ComponentProcessor.java:99)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.(JavacProcessingEnvironment.java:517)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:614)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:707)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1700(JavacProcessingEnvironment.java:97)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1029)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1163)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1108)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
at com.sun.tools.javac.main.Main.compile(Main.java:439)
… 11 more
Looking at the debug output of this build, I suspected that the annotation processor was using the wrong version of Guava, even though as far as I could tell the classpath being passed to GroovyCompile was correct.
Here’s the classpath logs for GroovyCompile, as you can see it looks like it’s pulling in the right version of Guava, highlighted in bold:
13:05:49.734 [DEBUG] [org.gradle.api.internal.tasks.compile.NormalizingGroovyCompiler] Java compiler arguments: -d /Users/werickson/AndroidStudioProjects/PureGroovyDaggerGuavaFailureDemo/build/classes/main -g -classpath /Users/werickson/.gradle/caches/modules-2/files-2.1/javax.annotation/jsr250-api/1.0/5025422767732a1ab45d93abfea846513d742dcf/jsr250-api-1.0.jar:/Users/werickson/.gradle/caches/modules-2/files-2.1/com.google.dagger/dagger-compiler/2.0-SNAPSHOT/d021463ddfd1b5c04a4118293391418843277a78/dagger-compiler-2.0-SNAPSHOT.jar:/Users/werickson/.gradle/caches/modules-2/files-2.1/com.google.dagger/dagger/2.0-SNAPSHOT/cadd885d40b816fd98ec11c4421786024da7ca76/dagger-2.0-SNAPSHOT.jar:/Users/werickson/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.4.0-rc-1/95865a25ae70317679c0c5739baaa884a7016422/groovy-2.4.0-rc-1.jar:/Users/werickson/.gradle/caches/modules-2/files-2.1/com.google.auto/auto-common/1.0-SNAPSHOT/42f4d366b24b3fdd56950e6cfaf0ecd141d101bf/auto-common-1.0-SNAPSHOT.jar:/Users/werickson/.gradle/caches/modules-2/files-2.1/com.squareup/javawriter/2.5.0/81241ff7078ef14f42ea2a8995fa09c096256e6b/javawriter-2.5.0.jar:/Users/werickson/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/18.0/cce0823396aa693798f8882e64213b1772032b09/guava-18.0.jar:/Users/werickson/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar:/Users/werickson/AndroidStudioProjects/PureGroovyDaggerGuavaFailureDemo/build/classes/main /Users/werickson/AndroidStudioProjects/PureGroovyDaggerGuavaFailureDemo/src/main/groovy/com/example/myapplication/AppModule.java
However, a little further down I saw this log output, indicating that another version of guava is being associated with the Gradle Compiler Daemon:
13:05:50.262 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process ‘Gradle Compiler Daemon 1’. Working directory: /Users/werickson/AndroidStudioProjects/PureGroovyDaggerGuavaFailureDemo Command: /Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk/Contents/Home/bin/java -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -cp /Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-base-services-2.2.1.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-core-2.2.1.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-cli-2.2.1.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-native-2.2.1.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-messaging-2.2.1.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/slf4j-api-1.7.7.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/logback-classic-1.0.13.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/logback-core-1.0.13.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/jul-to-slf4j-1.7.7.jar:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/guava-jdk5-17.0.jar org.gradle.process.internal.launcher.GradleWorkerMain ‘Gradle Compiler Daemon 1’
Gradle’s version of guava guava-jdk5-17.0.jar is missing the method that the Dagger annotation processor is complaining about.
So I wrote up another sample project with my own custom written annotation processor, to see what jars are really being utilized by annotation processors that are running in a Groovy joint compilation.
Here’s the output of that build:
$ ./gradlew build
:MyProcessor:compileJava
:MyProcessor:processResources
:MyProcessor:classes
:MyProcessor:jar
:compileJava UP-TO-DATE
:compileGroovy
==Classes Loaded From My Annotation Processor’s Classloader==
file:/Users/werickson/Downloads/PureGroovyGuavaFailureDemoWithCustomAnnotationProcessor/MyProcessor/build/libs/MyProcessor.jar
file:/Users/werickson/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.4.0-rc-1/95865a25ae70317679c0c5739baaa884a7016422/groovy-2.4.0-rc-1.jar
file:/Users/werickson/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/18.0/cce0823396aa693798f8882e64213b1772032b09/guava-18.0.jar
file:/Users/werickson/.gradle/caches/modules-2/files-2.1/com.google.dagger/dagger/2.0-SNAPSHOT/cadd885d40b816fd98ec11c4421786024da7ca76/dagger-2.0-SNAPSHOT.jar
file:/Users/werickson/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar
file:/Users/werickson/Downloads/PureGroovyGuavaFailureDemoWithCustomAnnotationProcessor/build/classes/main/
Queue is from: jar:file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/guava-jdk5-17.0.jar!/com/google/common/collect/Queues.class
==Classes Loaded From Queues ClassLoader==
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-base-services-2.2.1.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-core-2.2.1.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-cli-2.2.1.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-native-2.2.1.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/gradle-messaging-2.2.1.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/slf4j-api-1.7.7.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/logback-classic-1.0.13.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/logback-core-1.0.13.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/jul-to-slf4j-1.7.7.jar
file:/Users/werickson/.gradle/wrapper/dists/gradle-2.2.1-bin/88n1whbyjvxg3s40jzz5ur27/gradle-2.2.1/lib/guava-jdk5-17.0.jar
==Queue Methods==
public static java.util.concurrent.PriorityBlockingQueue com.google.common.collect.Queues.newPriorityBlockingQueue(java.lang.Iterable)
public static java.util.concurrent.PriorityBlockingQueue com.google.common.collect.Queues.newPriorityBlockingQueue()
public static java.util.concurrent.ConcurrentLinkedQueue com.google.common.collect.Queues.newConcurrentLinkedQueue()
public static java.util.concurrent.ConcurrentLinkedQueue com.google.common.collect.Queues.newConcurrentLinkedQueue(java.lang.Iterable)
public static java.util.concurrent.ArrayBlockingQueue com.google.common.collect.Queues.newArrayBlockingQueue(int)
public static java.util.PriorityQueue com.google.common.collect.Queues.newPriorityQueue()
public static java.util.PriorityQueue com.google.common.collect.Queues.newPriorityQueue(java.lang.Iterable)
public static java.util.concurrent.LinkedBlockingQueue com.google.common.collect.Queues.newLinkedBlockingQueue()
public static java.util.concurrent.LinkedBlockingQueue com.google.common.collect.Queues.newLinkedBlockingQueue(int)
public static java.util.concurrent.LinkedBlockingQueue com.google.common.collect.Queues.newLinkedBlockingQueue(java.lang.Iterable)
public static java.util.concurrent.SynchronousQueue com.google.common.collect.Queues.newSynchronousQueue()
public static int com.google.common.collect.Queues.drainUninterruptibly(java.util.concurrent.BlockingQueue,java.util.Collection,int,long,java.util.concurrent.TimeUnit)
public static java.util.Queue com.google.common.collect.Queues.synchronizedQueue(java.util.Queue)
public static int com.google.common.collect.Queues.drain(java.util.concurrent.BlockingQueue,java.util.Collection,int,long,java.util.concurrent.TimeUnit) throws java.lang.InterruptedException
As you can see in the output I’m getting different results for the jars that are used based on which class I pull the classloader from. If I pull the classloader from the AnnotationProcessor’s class, I get the jars I expect.
However, if I pull the classloader from the Queues class, I see the list of jars from the Gradle Compiler Daemon.
I think this clearly shows that there is a problem with the compiler daemon linking it’s classloader into the annotation processor.
If in this example I move AppModle.java from ‘src/main/groovy’ to ‘src/main/java’ I’ll get different results. Regardless of where I pull the classloader from, I get the set of jars that I expect.
Can you guys help me file a bug for this, and get the fix prioritized from the next Gradle release? This is blocking me from writing a Groovy application that utilizes Dagger.
Thanks!