Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataBindingComponent could not be resolved after bumping dagger to 2.43.1 #3522

Closed
xiahl33 opened this issue Aug 10, 2022 · 4 comments
Closed

Comments

@xiahl33
Copy link

xiahl33 commented Aug 10, 2022

Our project uses DataBinding and Dagger (no Hilt). After bumping dagger version from 2.39 to 2.43.1, we occasionally get a failure during the compileDebugJavaWithJavac task failed with this error:
error: InjectProcessingStep was unable to process 'Foo(com.xxx.MyDataBindings)' because 'androidx.databinding.DataBindingComponent' could not be resolved.

Dependency trace:
=> element (CLASS): com.xxx.Foo
=> element (METHOD): getDataBindingComponent()
=> type (EXECUTABLE method): ()androidx.databinding.DataBindingComponent
=> type (ERROR return type): androidx.databinding.DataBindingComponent

If type 'androidx.databinding.DataBindingComponent' is a generated type, check above for compilation errors that may have prevented the type from being generated. Otherwise, ensure that type 'androidx.databinding.DataBindingComponent' is on your classpath.
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 error

This problem happens randomly, and can not be reproduced every time. Unfortunately we have tried a sample project but cannot seem to reproduce the issue there.

We have read the error message, and there are no other compilation errors causing this issue.

Kotlin: 1.6.21 (no kapt)
AGP: 7.2.2
Dagger: 2.43.1
Java: 11

@bcorso
Copy link

bcorso commented Aug 10, 2022

This error means that the DataBindingComponent was not on the classpath when Dagger's processor ran.

Unfortunately, I don't think this is really something we can control/fix on the Dagger side, since we don't control what's on the classpath. My guess is that there's some race condition between javac and whatever androidx.databinding uses to generate their DataBindingComponent, but I don't really know enough about androidx.databinding to have any solutions there. You might try contacting the androidx.databinding team to see how to guarantee DataBindingComponent class is generated and on the classpath before javac compilation begins.

@cckroets
Copy link

Thanks for the quick reply @bcorso . I am on the same team as @xiahl33 .

We've already had issues in the past of DataBinding and Dagger causing flaky build failures 1+ years ago, and we resolved them by completely separating them (i.e. NOT having our dagger component extend DataBindingComponent). Instead we handwrite the implementation. This wasn't ideal, but since we could not get support from DataBinding team due to not being able to repro in a new project, this was our workaround.

Now the only connection between DataBinding and Dagger is that we have a class like

public class Foo {
    @Inject 
    public Foo() { }

    public DataBindingComponent publicMethodExposingDataBindingComponent() { ... }

The generated type is actually not needed by Dagger at all. Is it expected that Dagger needs to resolve every (public?) type and error out if it cannot be found? Is this a new intentional requirement of Dagger?

@bcorso
Copy link

bcorso commented Aug 10, 2022

Hi @cckroets, and thanks for the added context!

Normally we don't validate methods unless they're annotated with @Inject:

for (XMethodElement method : typeElement.getDeclaredMethods()) {
if (InjectionAnnotations.hasInjectAnnotation(method)) {
hasInjectedMembers = true;
ValidationReport report = validateMethod(method);
if (!report.isClean()) {
builder.addSubreport(report);
}
}
}

However, looks like the issue is that we validate the nearest enclosing type of all annotated elements (I even left a TODO to clean this up):

// TODO(b/201479062): It's inefficient to require validation of the entire enclosing
// type, we should try to remove this and handle any additional validation into the
// steps that need it.
superficialValidator.throwIfNearestEnclosingTypeNotValid(element);

For InjectProcessingStep, I think it's okay to remove this validation which should fix your issue.

I can send out a fix this week.

@cckroets
Copy link

Great to hear. Thanks @bcorso !

copybara-service bot pushed a commit that referenced this issue Aug 11, 2022
…ingStep.

Fixes #3522

The pre-validation should no longer be needed as `InjectValidator` validates everything itself. In addition, the pre-validation is overly broad, and validates types that are not necessary for Dagger to validate the class.

RELNOTES=Fixes #3522: Avoids pre-validating the nearest enclosing type in the InjectProcessingStep.
PiperOrigin-RevId: 466812816
copybara-service bot pushed a commit that referenced this issue Aug 11, 2022
…ingStep.

Fixes #3522

The pre-validation should no longer be needed as `InjectValidator` validates everything itself. In addition, the pre-validation is overly broad, and validates types that are not necessary for Dagger to validate the class.

RELNOTES=Fixes #3522: Avoids pre-validating the nearest enclosing type in the InjectProcessingStep.
PiperOrigin-RevId: 466812816
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants