Example:
@Module
class MyModule {
@Provides
static String provideStaticDependency() {
return "a static dependency";
}
private MyModule() {
throw new UnsupportedOperationException("No instances!");
}
}
@Subcomponent(modules = MyModule.class)
interface MySubComponent {
String staticDependency();
}
@Component
interface MyComponent {
MySubComponent subComponent();
}
Dagger complains:
error: MySubComponent requires modules which have no visible default constructors. Add the following modules as parameters to this method: MyModule
MySubComponent subComponent();
^
If I make the module constructor public, it solves the warning, but the generated code never calls that constructor (as is evidenced by the fact that my application never crashes).
That warning is also incorrectly worded.
On Fri, Mar 25, 2016 at 6:13 PM Tad Fisher [email protected] wrote:
Example:
@Moduleclass MyModule {
@Provides
static String provideStaticDependency() {
return "a static dependency";
}private MyModule() { throw new UnsupportedOperationException("No instances!"); }}
@Subcomponent(modules = MyModule.class)interface MySubComponent {
String staticDependency();
}@Componentinterface MyComponent {
MySubComponent subComponent();
}Dagger complains:
error: MySubComponent requires modules which have no visible default constructors. Add the following modules as parameters to this method: MyModule
MySubComponent subComponent();
^If I make the module constructor public, it solves the warning, but the
generated code never calls that constructor (as is evidenced by the fact
that my application never crashes).—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
https://github.com/google/dagger/issues/348
Er, I guess it's ambiguously worded. The indirect object is what the
default constructor constraint is applied to. On my first read it sounded
like the direct object, the subcomponent, required no visible default
constructors which makes no sense.
On Fri, Mar 25, 2016 at 7:45 PM Jake Wharton [email protected] wrote:
That warning is also incorrectly worded.
On Fri, Mar 25, 2016 at 6:13 PM Tad Fisher [email protected]
wrote:Example:
@Moduleclass MyModule {
@Provides
static String provideStaticDependency() {
return "a static dependency";
}private MyModule() { throw new UnsupportedOperationException("No instances!"); }}
@Subcomponent(modules = MyModule.class)interface MySubComponent {
String staticDependency();
}@Componentinterface MyComponent {
MySubComponent subComponent();
}Dagger complains:
error: MySubComponent requires modules which have no visible default constructors. Add the following modules as parameters to this method: MyModule
MySubComponent subComponent();
^If I make the module constructor public, it solves the warning, but the
generated code never calls that constructor (as is evidenced by the fact
that my application never crashes).—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
https://github.com/google/dagger/issues/348
Oh, interesting. I suppose that private constructors on modules with only static @Provides methods makes perfect sense and follows normal Java convention, but for whatever reason we just never thought to do it. I completely agree that it's a bug though.
Also happens for abstract modules of subcomponents which only have @Binds methods.
Right I've also encountered that. My usecase was this:
@SomeScope
class SomePresenter implements Presenter {
@Inject
public Repository repository;
@Inject
public SomePresenter() {}
}
//and then
public FooActivity extends Activity {
@Inject
Presenter presenter; // I want this to be SomePresenter
// but it's impossible when using constructor
// injection in SomePresenter
@Override
public void onCreate() {
getComponent().inject(this);
}
}
So I thought that it would work if I would keep constructor injection and add a module with @Binds to tell Dagger what it should inject. But as I'm using subcomponents it's not possible to use @Binds.
After all my only choice was to remove constructor injection and provide SomePresenter using only @Provides method in a standard Module. I don't like it because it forces me to write more boilerplate.
Is there any chance for improvements here anytime soon?
@mzgreen What if you tried:
@Inject
public SomePresenter(Repository repository) {
this.repository = repository;
}
@tadfisher It won't work.
I tried to remove all dependencies from SomePresenter like this:
@SomeScope
class SomePresenter implements Presenter {
@Inject
public SomePresenter() {}
}
//and then
public FooActivity extends Activity {
@Inject
Presenter presenter;
@Override
public void onCreate() {
getComponent().inject(this);
}
}
And it didn't work because Dagger can inject only SomePresenter. If I would request SomePresenter instead of Presenter in FooActivity then it would work but that's not what I want to achieve.
I guess this makes sense because how would Dagger know which one to inject if I would have many classes that implement Presenter interface?
That's why I wanted to use @Binds because I was hoping that it will fill the gap and tell Dagger that I want this implementation for this interface. It doesn't work with subcomponents though...
@mzgreen Right, that's a separate issue from this one. If you are injecting an interface, a module has to exist which provides a dependency of that type. Otherwise Dagger can not know which implementation of that interface to use (well, it _could_ if there is only a single implementation in scope, but that's not related to this issue).
@tadfisher I guess it's related because @Binds would help in this case but it's not possible to use in subcomponent.
I found a temporary fix:
@Module
public class SomeModule {
@SomeScope
@Provides
public static Presenter providePresenter(SomePresenter somePresenter) {
return somePresenter;
}
}
You'd still need a module with a @Binds method, so you wouldn't be able to elide the module entirely.
In any case, this issue is specifically about a compiler error when including a restricted constructor, so the problem you describe should probably be a separate issue.

Hey, thanks for the bump. I was actually working on this just the other day because it was annoying me too and we should have fix for the next release.
@gk5885 did you ever get to this one?
I was incredibly angy at this until I found that it went away after cleaning my project. Moral of the story, clean project early in troubleshooting.
Bump!
Just tested this out, and we don't require this anymore. It may be recent, so wait for the 2.22 release if it's not working in 2.21
Most helpful comment
Also happens for abstract modules of subcomponents which only have
@Bindsmethods.