google / dagger

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

Dagger 2.0.2 (and 2.6.1) lead to StackOverflowError on `compileDebugJavaWithJavac` #458

Closed autonomousapps closed 8 years ago

autonomousapps commented 8 years ago

I tried updating my Android project from version 2.0 to 2.6.1 and saw the following error message:

* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
> java.lang.StackOverflowError

I then tried various version of Dagger2 to see which version caused the problem. 2.0.1 works fine, but 2.0.2 exhibits it for me.

When I run the task with the --stacktrace flag, I see the following ad infinitum:

at dagger.internal.codegen.ModuleDescriptor$Factory.collectIncludedModules(ModuleDescriptor.java:116)
at dagger.internal.codegen.ModuleDescriptor$Factory.create(ModuleDescriptor.java:89)
at dagger.internal.codegen.ModuleDescriptor$Factory.collectIncludedModules(ModuleDescriptor.java:116)
at dagger.internal.codegen.ModuleDescriptor$Factory.create(ModuleDescriptor.java:89)

Any ideas? Let me know what I can provide that might help with diagnosis. Much obliged.

ronshapiro commented 8 years ago

Looks like a cycle in your @Module(includes = ...). this is a known issue that we need to fix.

autonomousapps commented 8 years ago

With that hint, I was able to track down a circular dependency among my modules. I removed them and successfully upgraded to Dagger 2.6.1. (Thank you!)

However, my next step was to replace some of my @Provides methods with @Binds methods. I did so (example below), and ran into another StackOverflowError. Sample output below the code example.

@Module(includes = { ... })
public abstract class PresenterModule {

    @Binds
    public abstract OneMvp.Presenter bindSplashHeadlessPresenter(OnePresenter presenter);

    @Binds
    public abstract TwoMvp.Presenter bindLoginPresenter(TwoPresenter presenter);

    @Binds
    public abstract ThreePresenter bindNowPlayingPresenter(ThreePresenter presenter);

Note there are no typos, there. We're doing some incremental refactoring and replacing our presenter references with interfaces. The first two return the concrete implementation as its interface. The third returns it as the implementation. Not sure if that's relevant.

at dagger.shaded.auto.common.MoreTypes$1.doHash(MoreTypes.java:71)
at com.google.common.base.Equivalence.hash(Equivalence.java:106)
at com.google.common.base.Equivalence$Wrapper.hashCode(Equivalence.java:220)
at dagger.internal.codegen.AutoValue_Key.hashCode(AutoValue_Key.java:70)
at com.google.common.collect.RegularImmutableMap.get(RegularImmutableMap.java:119)
at com.google.common.collect.RegularImmutableMap.get(RegularImmutableMap.java:111)
at com.google.common.collect.ImmutableSetMultimap.get(ImmutableSetMultimap.java:362)
at dagger.internal.codegen.BindingGraph$Factory$Resolver.getExplicitBindings(BindingGraph.java:673)
at dagger.internal.codegen.BindingGraph$Factory$Resolver.lookUpBindings(BindingGraph.java:357)
at dagger.internal.codegen.BindingGraph$Factory$Resolver.createDelegateBinding(BindingGraph.java:541)
at dagger.internal.codegen.BindingGraph$Factory$Resolver.createDelegateBindings(BindingGraph.java:528)
at dagger.internal.codegen.BindingGraph$Factory$Resolver.getExplicitBindings(BindingGraph.java:675)

Once again, any ideas are much appreciated.

ronshapiro commented 8 years ago

You're binding ThreePresenter to ThreePresenter (the same thing). Did you mean ThreeMvp.Presenter as the return type?

This is a bug which should be fixed in 2.7 (I'm releasing tomorrow) and then a follow-on fix in the next release by @gk5885 which should be even better.

On Wed, Sep 7, 2016, 5:53 PM Tony Robalik notifications@github.com wrote:

With that hint, I was able to track down a circular dependency among my modules. I removed them and successfully upgraded to Dagger 2.6.1. (Thank you!)

However, my next step was to replace some of my @Provides methods with @Binds methods. I did so (example below), and ran into another StackOverflowError. Sample output below the code example.

@Module(includes = { ... }) public abstract class PresenterModule {

@Binds
public abstract OneMvp.Presenter bindSplashHeadlessPresenter(OnePresenter presenter);

@Binds
public abstract TwoMvp.Presenter bindLoginPresenter(TwoPresenter presenter);

@Binds
public abstract ThreePresenter bindNowPlayingPresenter(ThreePresenter presenter);

Note there are no typos, there. We're doing some incremental refactoring and replacing our presenter references with interfaces. The first two return the concrete implementation as its interface. The third returns it as the implementation. Not sure if that's relevant.

at dagger.shaded.auto.common.MoreTypes$1.doHash(MoreTypes.java:71) at com.google.common.base.Equivalence.hash(Equivalence.java:106) at com.google.common.base.Equivalence$Wrapper.hashCode(Equivalence.java:220) at dagger.internal.codegen.AutoValue_Key.hashCode(AutoValue_Key.java:70) at com.google.common.collect.RegularImmutableMap.get(RegularImmutableMap.java:119) at com.google.common.collect.RegularImmutableMap.get(RegularImmutableMap.java:111) at com.google.common.collect.ImmutableSetMultimap.get(ImmutableSetMultimap.java:362) at dagger.internal.codegen.BindingGraph$Factory$Resolver.getExplicitBindings(BindingGraph.java:673) at dagger.internal.codegen.BindingGraph$Factory$Resolver.lookUpBindings(BindingGraph.java:357) at dagger.internal.codegen.BindingGraph$Factory$Resolver.createDelegateBinding(BindingGraph.java:541) at dagger.internal.codegen.BindingGraph$Factory$Resolver.createDelegateBindings(BindingGraph.java:528) at dagger.internal.codegen.BindingGraph$Factory$Resolver.getExplicitBindings(BindingGraph.java:675)

Once again, any ideas are much appreciated.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/google/dagger/issues/458#issuecomment-245431481, or mute the thread https://github.com/notifications/unsubscribe-auth/AAwY3aLmCxOqKYGGtNgrx4a9WUf94N9cks5qnzJegaJpZM4J3Pc_ .

autonomousapps commented 8 years ago

Yeah, that wasn't a typo, as I pointed out in my brief paragraph between the two code samples :)

I want to switch to @Binds to avoid having to update my @Provides methods every time I change the constructor params. In some cases, we're injecting our presenters as interfaces, whereas in other cases we're injecting them as the implementations. This is a temporary situation while we do incremental refactoring. Does binding to the same thing simply not work? Is there a better way to do that? Or do I just wait for 2.7 and use that?

Thanks again.

trevjonez commented 8 years ago

It just won't work. Best thing for now is to remove that @Binds line for the ThreePresenter until you have an interface in place to bind the implementation to.

Keep in mind that DAGger is the name of the library and DAG stands for directed acyclic graph, and you are explicitly adding a cycle.

The bug fixes they are pushing will simply catch this error and give more useful direct feedback about it.

I had a similar thing a while back. see: #390

autonomousapps commented 8 years ago

Oh, so I simply won't be able to use @Binds at all until we've added interfaces for all our presenters, or unless I decide to create a separate Module for those presenters that have interfaces. Gah.