sqldelight icon indicating copy to clipboard operation
sqldelight copied to clipboard

Dagger can't see new SQLDelight Queries types when they live in a multiplatform module

Open tfcporciuncula opened this issue 2 years ago • 6 comments

SQLDelight Version

1.5.0, 1.5.1, 1.5.2

Operating System

macOS Big Sur 11.6

Gradle Version

7.0.2 and 7.3

Kotlin Version

1.5.31

AGP Version

4.2.2, 7.0.3 and 7.1.0-beta03

Describe the Bug

The issue described here only happens when SQLDelight lives in a multiplatform module that is a dependency of the app module. I can only repro it starting from 1.5.0, and it also doesn't seem to be associated with any particular AGP version.


Whenever we create a new .sq file and @Provides the generated Queries type through Dagger, the build fails with the generic "ComponentProcessor was unable to process '...DbModule' because not all of its dependencies could be resolved", as if when Dagger runs, the SQLDelight generated file isn't available yet. After the build fails, the type is clearly available, though, as it's accessible in Android Studio. But building again still fails.

Sometimes a Build → Clean Project followed by a Make Project (or a Build → Rebuild Project) is enough to "fix" the issue, but some other times it's not and the project gets stuck in this error state, basically. There's some other arbitrary changes (e.g. adding or removing kapt.correctErrorTypes true, kapt.include.compile.classpath=false, or changing AGP versions) that also "fix" the issue, but whenever a new type from SQLDelight is added in the Dagger graph, the issue will pop up again (and then maybe a clean build will fix it, but maybe not).

Another interesting point is that if we add the new .sq file, then build, and then only after this first build add the provides method referencing it, then the error won't happen.


Here's a minimal reproducible example — even though everything looks good there, it'll most likely fail and be stuck in the error state the first time you build it. A change like removing kapt.correctErrorTypes true will make the error go away, but then you can bring it back by creating a new .sq file, adding the generated type in the graph (with a new provides method in the DbModule), and building the project.

Everything works great if SQLDelight lives in the app module or if the store module isn't multiplatform, you can test these scenarios by checking out earlier commits. The issue only shows up once the store module is multiplatform.

Stacktrace

With kapt.correctErrorTypes true:

> Task :store:kaptDebugKotlinAndroid FAILED
error: dagger.internal.codegen.ComponentProcessor was unable to process 'com.fredporciuncula.sqldelightdaggerissue.store.DbModule' because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.

dagger.internal.codegen.ComponentProcessor was unable to process 'com.fredporciuncula.sqldelightdaggerissue.store.DbModule' because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.

Execution failed for task ':store:kaptDebugKotlinAndroid'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction
   > java.lang.reflect.InvocationTargetException (no error message)

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':store:kaptDebugKotlinAndroid'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:145)
	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:282)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:143)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:131)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:402)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:389)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:382)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:368)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:61)
Caused by: org.gradle.workers.internal.DefaultWorkerExecutor$WorkExecutionException: A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction
	at org.gradle.workers.internal.DefaultWorkerExecutor$WorkItemExecution.waitForCompletion(DefaultWorkerExecutor.java:342)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForItemsAndGatherFailures(DefaultAsyncWorkTracker.java:142)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForItemsAndGatherFailures(DefaultAsyncWorkTracker.java:94)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForAll(DefaultAsyncWorkTracker.java:80)
	at org.gradle.internal.work.DefaultAsyncWorkTracker.waitForCompletion(DefaultAsyncWorkTracker.java:68)
	at org.gradle.api.internal.tasks.execution.TaskExecution$2.run(TaskExecution.java:247)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:224)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:207)
	at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:190)
	at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:168)
	at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:89)
	at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:40)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:53)
	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:50)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:50)
	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:40)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:68)
	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:38)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:36)
	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:29)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:61)
	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:42)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:60)
	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:27)
	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:188)
	at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:75)
	at org.gradle.internal.Either$Right.fold(Either.java:175)
	at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:59)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:73)
	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:48)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:38)
	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:27)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:109)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:56)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:56)
	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:73)
	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:44)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:89)
	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:50)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:114)
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:57)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:76)
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:50)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:93)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:93)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:43)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:31)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40)
	at org.gradle.api.internal.tasks.execution.TaskExecution$3.withWorkspace(TaskExecution.java:284)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:33)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:142)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:131)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:402)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:389)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:382)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:368)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:61)
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at org.jetbrains.kotlin.gradle.internal.KaptExecution.run(KaptWithoutKotlincTask.kt:288)
	at org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction.execute(KaptWithoutKotlincTask.kt:243)
	at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)
	at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)
	at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:206)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:214)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)
	... 3 more
Caused by: org.jetbrains.kotlin.kapt3.base.util.KaptBaseError: Error while annotation processing
	at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:132)
	at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:31)
	at org.jetbrains.kotlin.kapt3.base.Kapt.kapt(Kapt.kt:45)
	... 29 more

Without kapt.correctErrorTypes true:

> Task :store:compileDebugJavaWithJavac FAILED
/Users/fred/Repositories/sqldelight-dagger-issue/store/build/generated/source/kapt/debug/com/fredporciuncula/sqldelightdaggerissue/store/DbModule_ProvideDatabaseFactory.java:8: error: package error does not exist
import error.NonExistentClass;
            ^
/Users/fred/Repositories/sqldelight-dagger-issue/store/build/generated/source/kapt/debug/com/fredporciuncula/sqldelightdaggerissue/store/DbModule_ProvideDatabaseFactory.java:16: error: cannot find symbol
public final class DbModule_ProvideDatabaseFactory implements Factory<NonExistentClass> {
                                                                      ^
  symbol: class NonExistentClass
/Users/fred/Repositories/sqldelight-dagger-issue/store/build/generated/source/kapt/debug/com/fredporciuncula/sqldelightdaggerissue/store/DbModule_ProvideDatabaseFactory.java:27: error: cannot find symbol
  public NonExistentClass get() {
         ^
  symbol:   class NonExistentClass
  location: class DbModule_ProvideDatabaseFactory
/Users/fred/Repositories/sqldelight-dagger-issue/store/build/generated/source/kapt/debug/com/fredporciuncula/sqldelightdaggerissue/store/DbModule_ProvideDatabaseFactory.java:36: error: cannot find symbol
  public static NonExistentClass provideDatabase(DbModule instance, Context context) {
                ^
  symbol:   class NonExistentClass
  location: class DbModule_ProvideDatabaseFactory
4 errors

Gradle Build Script

tfcporciuncula avatar Nov 16 '21 17:11 tfcporciuncula

I don't think Dagger can do much here as this seems related to how KAPT gives Dagger's processor its inputs and they not being quite right, something Dagger does not control. Specifically, it seems that the javac invocation done by KAPT does not pickup SQLDelight generated classes, so for Dagger it is as if those new generated classes are not in the classpath. This might be an issue more with how SQLDelight plugin and KAPT multiplatform interact with each other during incremental compilations.

Here is what I am observing, using your sample project (thanks for providing one!).

When kapt verbose is enabled:

kapt.verbose=true // in gradle.properties
kapt { // in build.gradle were kapt plugin is applied
    javacOptions {
        option("-XprintProcessorInfo")
        option("-XprintRounds")
    }
}

and creating that Queries2.sq and uncommeting the lines in DbModule the inputs to Dagger does not include Queries2Queries and only included DbModule:

Annotation processors: 
AP options: {kapt.kotlin.generated=/Users/danysantiago/Downloads/sqldelight-dagger-issue-main/store/build/generated/source/kaptKotlin/debug}
Javac options: {-XprintProcessorInfo=, -XprintRounds=, -source=1.8}
[incremental apt] Changed files: [/Users/danysantiago/Downloads/sqldelight-dagger-issue-main/store/build/tmp/kapt3/stubs/debug/com/fredporciuncula/sqldelightdaggerissue/store/DbModule.java]
[incremental apt] Compiled sources directories: /Users/danysantiago/Downloads/sqldelight-dagger-issue-main/store/build/tmp/kotlin-classes/debug, /Users/danysantiago/Downloads/sqldelight-dagger-issue-main/store/build/intermediates/javac/debug/classes
[incremental apt] Cache directory for incremental compilation: /Users/danysantiago/Downloads/sqldelight-dagger-issue-main/store/build/tmp/kapt3/incApCache/debug
[incremental apt] Changed classpath names: 

[INFO] Need to discovery annotation processors in the AP classpath
[INFO] Use own ClassLoader for processor 'dagger.internal.codegen.ComponentProcessor'
[INFO] Annotation processors: dagger.internal.codegen.ComponentProcessor
[INFO] Processing java sources with annotation processors: /Users/danysantiago/Downloads/sqldelight-dagger-issue-main/store/build/tmp/kapt3/stubs/debug/com/fredporciuncula/sqldelightdaggerissue/store/DbModule.java, /Users/danysantiago/Downloads/sqldelight-dagger-issue-main/store/build/tmp/kapt3/stubs/debug/error/NonExistentClass.java
[INFO] Processing types with annotation processors: 
error: dagger.internal.codegen.ComponentProcessor was unable to process 'com.fredporciuncula.sqldelightdaggerissue.store.DbModule' because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.
Round 1:
        input files: {com.fredporciuncula.sqldelightdaggerissue.store.DbModule, error.NonExistentClass}
        annotations: [kotlin.Metadata, dagger.Module, org.jetbrains.annotations.NotNull, javax.inject.Singleton, dagger.Provides]
        last round: false
Processor org.jetbrains.kotlin.kapt3.base.ProcessorWrapper matches [dagger.Module, dagger.Provides] and returns false.
Round 2:
        input files: {}
        annotations: []
        last round: true
[INFO] Analyzing sources structure took 0[ms].
[INFO] Annotation processing complete, errors: 1, warnings: 0
[INFO] Annotation processor stats:
[INFO] dagger.internal.codegen.ComponentProcessor: total: 204 ms, init: 149 ms, 2 round(s): 40 ms, 15 ms
File Object History : []
Open Type Names     : []
Gen. Src Names      : []
Gen. Cls Names      : []
Agg. Gen. Src Names : []
Agg. Gen. Cls Names : []

FAILURE: Build failed with an exception.

With correctErrorTypes = true KAPT will not check if the class is in the classpath and the stubs will look fine:

    @org.jetbrains.annotations.NotNull()
    @dagger.Provides()
    public final Queries2Queries provideQueries2(@org.jetbrains.annotations.NotNull()
    MyDatabase database) {
        return null;
    }

But when Dagger tires to read the return type it will find a TYPE_ERROR for which it'll wait one or more rounds to see if the class is generated until it gives up and throw the generic message: dagger.internal.codegen.ComponentProcessor was unable to process 'com.fredporciuncula.sqldelightdaggerissue.store.DbModule' because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.

When correctErrorTypes = false, KAPT replaces types that can't resolve with the NonExistentClass which will help Dagger generate a bit of code but ultimately it will be wrong.

    @org.jetbrains.annotations.NotNull()
    @dagger.Provides()
    public final error.NonExistentClass provideQueries1(@org.jetbrains.annotations.NotNull()
    error.NonExistentClass database) {
        return null;
    }

However this is a good indicator that even KAPT can't find the SQLDelight generated class during that incremental compilation.

I'd suggest filling an issue to the SQLDelight team as they will know more how their Gradle plugin interacts with KMP and how it should register newly generated sources so other compile tasks picks them up.

Note that the semi arbitrary actions of changing AGP versions, or turning ON/OFF correctErrorTypes work, because those invalidate the projects incremental data and a full-build is done, which works fine. The issue is related to incremental compilations.


EDIT: I for some reason thought this issue was in the Dagger repo so responded from that perspective (ups!). But anyway, this info can be useful and the issue is already in the right place, so I'll leave it all as-is.

danysantiago avatar Nov 19 '21 17:11 danysantiago

Update: the problem still persists on v1.5.3.

But we found a workaround, which is to split SQLDelight codegen and kapt to different modules, a la SDKSearch (with :store:item and :store:item:android-sql. This way the codegen runs first and only then kapt gets executed.

leandrofavarin avatar Nov 24 '21 13:11 leandrofavarin

i suspect its related to this change

AlecKazakova avatar Nov 24 '21 13:11 AlecKazakova

I wonder if theres a way to add back the registerJavaGeneratingTask call a projects gradle file to fix it

AlecKazakova avatar Nov 24 '21 13:11 AlecKazakova

I spent some time today trying to figure this out, but can't. It seems nowhere I put the generate task in the execution order helps dagger see the symbols, like Daniel said it's incremental compilation related but I also don't know why my current setup wouldn't work there: we correctly register the generated directory as source, but there must be something else to hook into to let kotlin know it needs to check our generated directory for invalidation.

AlecKazakova avatar Apr 14 '22 19:04 AlecKazakova

I'm facing same problem after bumped AGP version to 7.0

I use androidComponents API workaround like this

androidComponents {
    beforeVariants(selector().all()) {
        android.sourceSets.maybeCreate(name).java.srcDir(
            layout.buildDirectory.dir("generated/sqldelight/code/DB_NAME/${buildType}")
        )
    }
}

Maybe related gradle plugin problem....??? https://github.com/google/protobuf-gradle-plugin/issues/714

RyuNen344 avatar Feb 19 '24 00:02 RyuNen344