Getting stabbed by Dagger on Android


Did you read the title?It saysI got stabbed, by Dagger, on Android. The non-technical reader would assume something serious occurred followed by hospitalization. Those who know me are already wondering what the dependency injection framework I’ve come to love and how it could have any pointy edges. While I actually have physically been stabbed in the not too distant past (long embarrassing story and I don’t wanna get into it) I can assure you today’s situation does not involve anything breaking my skin. Hi, I’m Cliff. You’re here because you’ve been stabbed by Dagger. You may not need bandages or medical care but it hurts kinda bad. I’m here because I was bleeding a little while ago and I want to share my experience.

The catalyst for today’s post revolves around the suspicious error messages I was seeing from Dagger from time to time. I sort of know how to use it pretty well but when I’m in a rush I tend to make subtle mistakes that lead to even more subtle but hard to decipher error messages. These errors don’t always steer me to the source of the problem, rather they leave me with a feeling of, “that doesn’t make sense!” As Dr. House says, “When something doesn’t make sense, one of your assumptions is flawed.” (I love House!) All rambling aside, let’s get to the important part. Below I’ll list a few error messages along with what they might be trying to tell you. Remember, the best way to debug a program is to force an error early on and get used to the random messages it generates. I’m saving you a bit of time by doing some of this rework for you in Dagger.

Error:
java.lang.IllegalArgumentException: No inject registered for members/com.your.package.YourInjectedClass. You must explicitly add it to the 'injects' option in one of your modules.

at dagger.ObjectGraph$DaggerObjectGraph.getInjectableTypeBinding(ObjectGraph.java:302)
at dagger.ObjectGraph$DaggerObjectGraph.inject(ObjectGraph.java:279)
at com.your.package.YourInjectedClass.init(YourInjectedClass:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)

Cause:
You may have tried to inject a class that is not declared in the Module you’re using to do injection. For eg., if you call ObjectGraph.create(MyModule.class).inject(this); and this object does not appear in MyModule then you probably should add it to the @Module annotation like so:
@Module(library = true, injects = YourInjectedClass.class)

Error:
Compilation completed with 1 error and 0 warnings in 2s 455ms
/Users/you/src/YourProject/src/test/java/your/package/YourInjectedClass.java
Error:Error:line (37)java: your.package.someInjectedDependency could not be bound with key your.package.someInjectedDependency required by YourInjectedClass for YourInjectedClassModule

Cause:
You may be missing a providing method in our module or more likely you’ve forgotten the @Provides annotation. If YourInjectedClass decades an injected variable of type your.package.someInjectedDependency, check that your.package.someInjectedDependency is returned from some providing method and that the method includes the @Provides annotation like so:

@Provides
public someInjectedDependency providesSomeInjectedDependency() {
return new someInjectedDependency();
}

Error:
java.lang.UnsupportedOperationException: No no-args constructor on at com.your.package.YourInjectedClass$YourInjectedClassModule$$ModuleAdapter

at dagger.internal.ModuleAdapter.newModule(ModuleAdapter.java:58)
at dagger.internal.Modules.loadModules(Modules.java:41)
at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:174)
at dagger.ObjectGraph$DaggerObjectGraph.access$000(ObjectGraph.java:138)
at dagger.ObjectGraph.create(ObjectGraph.java:129)
at com.your.package.YourInjectedClass.setUp(YourInjectedClass.java:22)

Cause:
I got this error by doing something really strange/non-standard. It just means that it cannot instantiate your Module class. In my case I had defined my module class in the same file as the class that was asking for injection but outside the class definition. (This is outside the last curly brace enclosing the contents of the class’ methods.) I then moved inside the class definition but forgot to make it a static. This caused Dagger to not be able invoke the constructor because that only works for static inner classes… if none of this makes any sense to you don’t think about. Just know that the error above means that you should check the visibility of your module class (eg. is it a private class or a public class? Does it have a public no-arg constructor? Is it in the classpath?)

There’s other weird errors I’m trying to get used to and I’ll either post here or write a new article as I discover them.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s