Dagger: @BindsInstance on parameter triggering ISE for missing binding

Created on 2 Apr 2019  路  3Comments  路  Source: google/dagger

Caused by: java.lang.IllegalStateException: no component requirement expression found for ComponentRequirement{kind=BOUND_INSTANCE, wrappedType=dagger.shaded.auto.common.MoreTypes$TypeEquivalence@6faecbf3.wrap(java.lang.String), overrideNullPolicy=Optional.empty, key=Optional[java.lang.String], variableName=string}
        at dagger.internal.codegen.ComponentRequirementExpressions.getExpression(ComponentRequirementExpressions.java:113)
        at dagger.internal.codegen.ComponentRequirementExpressions.getExpression(ComponentRequirementExpressions.java:85)
        at dagger.internal.codegen.ComponentRequirementBindingExpression.getDependencyExpression(ComponentRequirementBindingExpression.java:43)
        at dagger.internal.codegen.BindingExpression.getDependencyExpressionForComponentMethod(BindingExpression.java:46)
        at dagger.internal.codegen.BindingExpression.getComponentMethodImplementation(BindingExpression.java:64)
        at dagger.internal.codegen.ComponentBindingExpressions.getComponentMethod(ComponentBindingExpressions.java:219)
        at dagger.internal.codegen.ComponentImplementationBuilder.addInterfaceMethods(ComponentImplementationBuilder.java:183)
        at dagger.internal.codegen.ComponentImplementationBuilder.build(ComponentImplementationBuilder.java:137)
        at dagger.internal.codegen.ComponentImplementationFactory.createComponentImplementationUncached(ComponentImplementationFactory.java:91)
        at dagger.internal.codegen.ComponentImplementationFactory.lambda$createComponentImplementation$0(ComponentImplementationFactory.java:61)
        at dagger.internal.codegen.Util.reentrantComputeIfAbsent(Util.java:94)
        at dagger.internal.codegen.ComponentImplementationFactory.createComponentImplementation(ComponentImplementationFactory.java:58)
        at dagger.internal.codegen.ComponentGenerator.write(ComponentGenerator.java:66)
        at dagger.internal.codegen.ComponentGenerator.write(ComponentGenerator.java:35)
        at dagger.internal.codegen.SourceFileGenerator.generate(SourceFileGenerator.java:72)
        at dagger.internal.codegen.SourceFileGenerator.generate(SourceFileGenerator.java:63)
        at dagger.internal.codegen.ComponentProcessingStep.generateComponent(ComponentProcessingStep.java:160)
        at dagger.internal.codegen.ComponentProcessingStep.processRootComponent(ComponentProcessingStep.java:139)
        at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:121)
        at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:49)
        at dagger.internal.codegen.TypeCheckingProcessingStep.lambda$process$0(TypeCheckingProcessingStep.java:51)
        at com.google.common.collect.RegularImmutableMap.forEach(RegularImmutableMap.java:186)
        at dagger.internal.codegen.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:48)
        at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:114)
        at dagger.internal.codegen.ComponentProcessingStep.process(ComponentProcessingStep.java:49)
        at dagger.internal.codegen.DaggerStatisticsCollectingProcessingStep.process(DaggerStatisticsCollectingProcessingStep.java:52)
        at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:330)
        at dagger.shaded.auto.common.BasicAnnotationProcessor.process(BasicAnnotationProcessor.java:181)
        at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.process(DelegatingProcessor.java:62)
        at org.gradle.api.internal.tasks.compile.processing.DynamicProcessor.process(DynamicProcessor.java:52)
        at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.process(DelegatingProcessor.java:62)
        at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.access$401(TimeTrackingProcessor.java:37)
        at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$5.create(TimeTrackingProcessor.java:99)
        at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$5.create(TimeTrackingProcessor.java:96)
        at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.track(TimeTrackingProcessor.java:117)
        at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.process(TimeTrackingProcessor.java:96)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:972)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:888)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1214)
        at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1326)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1258)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:936)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:147)
        ... 106 more

The code is

package com.example;

import dagger.BindsInstance;
import dagger.Component;

@Component
public interface BuilderBindsInstanceOnParameter {
  String string();

  @Component.Builder
  interface Builder {
    Builder string(@BindsInstance String one);
    BuilderBindsInstanceOnParameter build();
  }
}

Moving @BindsInstance from the parameter to the method makes the error go away. I actually caught this prior to 2.22 but I thought it was user error. I've only since discovered that (I think) it's not my fault 馃榿

bug

Most helpful comment

I think I've figured out why it's failing, and it's pretty dumb (and is based on a bad assumption on our part that didn't get caught in the testing).

The problem is:

  • The code that generates the ComponentRequirement for the @BindsInstance parameter uses the parameter name as the variable name; @BindsInstance on the method uses the method name.
  • Some other code creates another ComponentRequirement instance for the binding, assuming the method name is the variable name (because the method is still considered the bindingElement for the binding).
  • Equality of ComponentRequirement instances takes the variable name into account, and no exact match is found.

As a workaround, giving the parameter the same name as the method works, but obviously that should not be required.

All 3 comments

I did see that the test for adding this feature is very nearly exactly the same thing as above, so I'm not sure why it's failing.

I think I've figured out why it's failing, and it's pretty dumb (and is based on a bad assumption on our part that didn't get caught in the testing).

The problem is:

  • The code that generates the ComponentRequirement for the @BindsInstance parameter uses the parameter name as the variable name; @BindsInstance on the method uses the method name.
  • Some other code creates another ComponentRequirement instance for the binding, assuming the method name is the variable name (because the method is still considered the bindingElement for the binding).
  • Equality of ComponentRequirement instances takes the variable name into account, and no exact match is found.

As a workaround, giving the parameter the same name as the method works, but obviously that should not be required.

(Note: this is fixed in 2.22.1)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

HiroyukTamura picture HiroyukTamura  路  3Comments

pedrovarela86 picture pedrovarela86  路  3Comments

feinstein picture feinstein  路  3Comments

SAGARSURI picture SAGARSURI  路  3Comments

Axrorxoja picture Axrorxoja  路  3Comments