google / dagger

A fast dependency injector for Android and Java.
https://dagger.dev
Apache License 2.0
17.35k stars 2k forks source link

IllegalStateException: Unsupported nesting ANONYMOUS on hilt 2.47 #3962

Closed Tougee closed 11 months ago

Tougee commented 12 months ago

Upgrade Hilt from 2.46.1 to 2.47 and meet this error, seems this has been fixed few versions ago. https://github.com/google/dagger/issues/3760 https://issuetracker.google.com/issues/232742201

I've upgraded Android compile sdk to 34 recently, not sure if these have connections.

Execution failed for task ':app:hiltJavaCompileDebug'.
> java.lang.IllegalStateException: Unsupported nesting ANONYMOUS
theobch commented 12 months ago

Can relate, having this crash too

bcorso commented 12 months ago

Thanks for the report! Unfortunately, we will need some more information on how to reproduce this in order to take a closer look at the issue.

If you have any more details or guesses where this may be failing in your code please let us know. If not, you can typically find more information by attaching a debugger as described in https://github.com/google/dagger/issues/3513#issuecomment-1206591106.

We'll also add more information to the error message itself. I can update this chat once that has been submitted and you can try it out using the HEAD-SNAPSHOT artifact

theobch commented 11 months ago

Hi @bcorso,

Thanks for support. I've tried the HEAD-SNAPSHOT version, but nothing has changed regarding error message, do you confirm no new version has been pushed yet (at the time of writing this comment) ?

I've tried debug AggregatedDepsMetadat#create as stated in the link you've posted, but the last class being reported doesn't seem to be different from other modules in the codebase I'm working on (i.e a simple interface which binds a concrete implementation to its interface).

I've also changed ALL Kotlin Object / functional interface (either used as top-level entity or as submodules) as it could (apparently) be a problem: https://issuetracker.google.com/issues/232742201#comment3 and also because I interpret message as a potential problem with anonymous implementation, but same things, nothing changed

Finally, I've put a breakpoint inandroidx.room.compiler.processing.javac.kotlin.Element.internalName but it is never reached, as apparently the JvmDescriptorUtils.kt (which contains this Element#internalName extension) is located in dagger.spi.shaded.androidx.room and I can't manage to obtain source code to but a breakpoint in it, as stated in the stacktrace: https://gist.github.com/theobch/3fbe6b7ae9fcceee9c0853ed1fd8396f

bcorso commented 11 months ago

I've tried the HEAD-SNAPSHOT version, but nothing has changed regarding error message, do you confirm no new version has been pushed yet (at the time of writing this comment) ?

No, it has not been pushed yet. I'll update this thread once it's out.

Finally, I've put a breakpoint in androidx.room.compiler.processing.javac.kotlin.Element.internalName but it is never reached, as apparently the JvmDescriptorUtils.kt (which contains this Element#internalName extension) is located in dagger.spi.shaded.androidx.room and I can't manage to obtain source code to but a breakpoint in it

If you have access to https://github.com/google/dagger/blob/master/java/dagger/internal/codegen/validation/InjectValidator.java#L380 source then you should be able to get pretty close to where the issue is happening in your code by inspecting the elements there.

ntlam6 commented 11 months ago

I have the same problem. When running debug for https://github.com/google/dagger/blob/master/java/dagger/internal/codegen/validation/InjectValidator.java#L380, the last Element was a regular Fragment with nothing special so im kinda stuck

theobch commented 11 months ago

Hi @bcorso, Hope you're doing well. Is there an ETA you can share about the update which contains better logs ? Thanks,

bcorso commented 11 months ago

Hi @theobch, sorry we were waiting on a few dependencies to be updated.

The fix should be in the HEAD-SNAPSHOT artifacts once this run finished: https://github.com/google/dagger/actions/runs/5665122541

MyDogTom commented 11 months ago

Thanks to the recent snapshot, I was able to identify the exact place in my code that causes an error. However, I don't fully understand why Dagger complains about it. Note: I use only Dagger without Hilt.

There is a simplified snippet

package com.example.my.fragment

class MyFragment {

    @Inject lateinit var injectedField: InjectedFieldType

    private val anotherField by lazy {
        object: MyInterface {
            override fun doSomething() {
                injectedField.doWork()
            }
        }
    }
}

anotherField causes the problem. If I make it public, then compilation passes. But this field is not injected by Dagger. Am I missing something?

At first I was thinking that it is somehow related to injectedField usage inside anotherField. When I remove this usage, compilation still fails with the same error.

package com.example.my.fragment

class MyFragment {

    @Inject lateinit var injectedField: InjectedFieldType

    private val anotherField by lazy {
        object: MyInterface {
            override fun doSomething() {
-                injectedField.doWork()
+                TODO()
            }
        }
    }
}

Here is the full error

Caused by: com.sun.tools.javac.processing.AnnotationProcessingError: java.lang.IllegalStateException: Unsupported nesting ANONYMOUS - On element <unnamed>.fragment.MyFragment.<init>.anotherField$2.invoke.<unnamed>
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(Unknown Source)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(Unknown Source)
        ... 38 more
Caused by: java.lang.IllegalStateException: Unsupported nesting ANONYMOUS - On element <unnamed>.fragment.MyFragment.<init>.anotherField$2.invoke.<unnamed>
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin.JvmDescriptorTypeVisitor.elementError(JvmDescriptorUtils.kt:192)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin.JvmDescriptorTypeVisitor.getInternalName(JvmDescriptorUtils.kt:172)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin.JvmDescriptorTypeVisitor.visitDeclared(JvmDescriptorUtils.kt:117)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin.JvmDescriptorTypeVisitor.visitDeclared(JvmDescriptorUtils.kt:113)
        at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Unknown Source)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin.JvmDescriptorTypeVisitor.visitExecutable(JvmDescriptorUtils.kt:139)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin.JvmDescriptorTypeVisitor.visitExecutable(JvmDescriptorUtils.kt:113)
        at jdk.compiler/com.sun.tools.javac.code.Type$MethodType.accept(Unknown Source)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin.JvmDescriptorUtilsKt.descriptor(JvmDescriptorUtils.kt:57)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin.JvmDescriptorUtilsKt.descriptor(JvmDescriptorUtils.kt:55)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacExecutableElement$jvmDescriptor$2.invoke(JavacExecutableElement.kt:32)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacExecutableElement$jvmDescriptor$2.invoke(JavacExecutableElement.kt:31)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacExecutableElement.getJvmDescriptor(JavacExecutableElement.kt:31)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacTypeElement$_declaredMethods$2.invoke(JavacTypeElement.kt:183)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacTypeElement$_declaredMethods$2.invoke(JavacTypeElement.kt:161)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacTypeElement.get_declaredMethods(JavacTypeElement.kt:161)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacTypeElement.getSyntheticMethodsForAnnotations(JavacTypeElement.kt:205)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacFieldElement$syntheticMethodForAnnotations$2.invoke(JavacFieldElement.kt:55)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacFieldElement$syntheticMethodForAnnotations$2.invoke(JavacFieldElement.kt:53)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacFieldElement.getSyntheticMethodForAnnotations(JavacFieldElement.kt:53)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacFieldElement.getAllAnnotations(JavacFieldElement.kt:39)
        at dagger.spi.shaded.androidx.room.compiler.processing.XAnnotated.getAnnotations(XAnnotated.kt:38)
        at dagger.spi.shaded.androidx.room.compiler.processing.XAnnotated.hasAnnotation(XAnnotated.kt:88)
        at dagger.spi.shaded.androidx.room.compiler.processing.XAnnotated.hasAnyAnnotation(XAnnotated.kt:100)
        at dagger.internal.codegen.binding.InjectionAnnotations.hasInjectAnnotation(InjectionAnnotations.java:337)
        at dagger.internal.codegen.validation.InjectValidator.validateForMembersInjectionInternalUncached(InjectValidator.java:372)
        at dagger.internal.codegen.base.Util.reentrantComputeIfAbsent(Util.java:33)
        at dagger.internal.codegen.validation.InjectValidator.validateForMembersInjectionInternal(InjectValidator.java:361)
        at dagger.internal.codegen.validation.InjectValidator.validateForMembersInjection(InjectValidator.java:357)
        at dagger.internal.codegen.validation.InjectBindingRegistryImpl.tryRegisterMembersInjectedType(InjectBindingRegistryImpl.java:305)
        at dagger.internal.codegen.validation.InjectBindingRegistryImpl.getOrFindMembersInjectionBinding(InjectBindingRegistryImpl.java:367)
        at dagger.internal.codegen.binding.BindingGraphFactory$Resolver.lookUpMembersInjectionBinding(BindingGraphFactory.java:466)
        at dagger.internal.codegen.binding.BindingGraphFactory$Resolver.resolveMembersInjection(BindingGraphFactory.java:770)
        at dagger.internal.codegen.binding.BindingGraphFactory$Resolver.access$1300(BindingGraphFactory.java:302)
        at dagger.internal.codegen.binding.BindingGraphFactory.lambda$createLegacyBindingGraph$5(BindingGraphFactory.java:208)
        at dagger.internal.codegen.binding.BindingGraphFactory.createLegacyBindingGraph(BindingGraphFactory.java:205)
        at dagger.internal.codegen.binding.BindingGraphFactory.createLegacyBindingGraph(BindingGraphFactory.java:234)
        at dagger.internal.codegen.binding.BindingGraphFactory.create(BindingGraphFactory.java:112)
        at dagger.internal.codegen.processingstep.ComponentProcessingStep.processRootComponent(ComponentProcessingStep.java:117)
        at dagger.internal.codegen.processingstep.ComponentProcessingStep.process(ComponentProcessingStep.java:88)
        at dagger.internal.codegen.processingstep.ComponentProcessingStep.process(ComponentProcessingStep.java:50)
        at dagger.internal.codegen.processingstep.TypeCheckingProcessingStep.lambda$process$0(TypeCheckingProcessingStep.java:82)
        at com.google.common.collect.RegularImmutableMap.forEach(RegularImmutableMap.java:196)
        at dagger.internal.codegen.processingstep.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:70)
        at dagger.internal.codegen.processingstep.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:48)
        at dagger.spi.shaded.androidx.room.compiler.processing.XProcessingStep.process(XProcessingStep.kt:59)
        at dagger.spi.shaded.androidx.room.compiler.processing.CommonProcessorDelegate.processRound(XBasicAnnotationProcessor.kt:130)
        at dagger.spi.shaded.androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor.process(JavacBasicAnnotationProcessor.kt:73)
        at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt:90)
        at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:197)
        ... 43 more
danysantiago commented 11 months ago

Thanks for the sample code, we have an idea on what is going on.

To workaround the issue for now, please specify the property type as to avoid Kotlin's type resolution using an anonymous class, i.e.:

+ private val anotherField: MyInterface by lazy {
- private val anotherField by lazy {
        object: MyInterface {
            override fun doSomething() {
                injectedField.doWork()
            }
        }
    }
theobch commented 11 months ago

Hi @theobch, sorry we were waiting on a few dependencies to be updated.

No problem, thanks for the hard work ! We will try on our codebase to check the culprit, thanks again

theobch commented 11 months ago

Can confirm, issue is related to a type not specified in one of our Fragment:

-    private val scrollToLastMessageDataObserver by lazy {
+    private val scrollToLastMessageDataObserver: RecyclerView.AdapterDataObserver by lazy {
        object : RecyclerView.AdapterDataObserver() {
            override fun onItemRangeInserted(position: Int, count: Int) {
                 […]
            }
        }
    }

Thanks again for the snapshot, helped a lot !

danysantiago commented 11 months ago

Fixed in https://github.com/androidx/androidx/commit/da6bd1a2f983372fd3ce34753d0b93bac7ec0361 which is the library Dagger uses for processing.

onXAdamBrown commented 11 months ago

So just to be clear we're waiting for a new Dagger release to fix this? Any chance of a point release for it?

bcorso commented 11 months ago

So just to be clear we're waiting for a new Dagger release to fix this?

Yes, that's correct.

Any chance of a point release for it?

Yes, I'll try to get a release out early next week.

bcorso commented 10 months ago

@onXAdamBrown Just fyi, we have a 2.48 release planned for next week, so we're going to push this into that release.

(Note: Dagger doesn't maintain multiple release branches so it would be difficult for us to cut a 2.47.1 release with only this change without including the other larger (potentially breaking) changes.)