Dagger can't find injectable members on a module

I’m using Dagger for dependency injection in an Android project, and can compile and build the app fine. The object graph appears to be correct and working, but when I add dagger-compiler as a dependency to get errors at compile time, it reports some bizarre errors:

[ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \
    .mgodroid.io.NodeIndexTask> required by com.atami \
    .mgodroid.ui.NodeIndexListFragment for com.atami.mgodroid \
    .modules.OttoModule
[ERROR] error: No binding for com.squareup.tape.TaskQueue<com.atami \
    .mgodroid.io.NodeTask> required by com.atami \
    .mgodroid.ui.NodeFragment for com.atami.mgodroid.modules.OttoModule
[ERROR] error: No injectable members on com.squareup.otto.Bus. Do you want 
     to add an injectable constructor? required by com.atami. \
     mgodroid.io.NodeIndexTaskService for 
     com.atami.mgodroid.modules.TaskQueueModule

The Otto error looks like the one Eric Burke mentions in his Android App Anatomy presentation about not having a @Provides annotation, but as you can see below I do.

  • Black screen before Splash screen appear in android
  • How to solve “This element has no attached source and the Javadoc could not be found in the attached Javadoc”?
  • Difference between SurfaceView and GLSurfaceView in Android
  • Unexpected error while processing hprof file: null
  • Does having variations of gestures in gesture library improve recognition?
  • Android - Google Maps API v2 - SupportMapFragment Errors
  • My Otto and TaskQueue modules are as follows:

    @Module(
            entryPoints = {
                    MGoBlogActivity.class,
                    NodeIndexListFragment.class,
                    NodeFragment.class,
                    NodeActivity.class,
                    NodeCommentFragment.class,
                    NodeIndexTaskService.class,
                    NodeTaskService.class
            }
    )
    public class OttoModule {
    
        @Provides
        @Singleton
        Bus provideBus() {
            return new AsyncBus();
        }
    
        /**
         * Otto EventBus that posts all events on the Android main thread
         */
        private class AsyncBus extends Bus {
            private final Handler mainThread = new Handler(Looper.getMainLooper());
    
            @Override
            public void post(final Object event) {
                mainThread.post(new Runnable() {
                    @Override
                    public void run() {
                        AsyncBus.super.post(event);
                    }
                });
            }
        }
    }
    

    @Module(
        entryPoints = {
            NodeIndexListFragment.class,
            NodeFragment.class,
            NodeIndexTaskService.class,
            NodeTaskService.class
        }
    )
    public class TaskQueueModule {
    
        private final Context appContext;
    
        public TaskQueueModule(Context appContext) {
            this.appContext = appContext;
        }
    
        public static class IOTaskInjector<T extends Task> 
            implements TaskInjector<T> {
    
            Context context;
    
            /**
             * Injects Dagger dependencies into Tasks added to TaskQueues
             *
             * @param context the application Context
             */
            public IOTaskInjector(Context context) {
                this.context = context;
            }
    
            @Override
            public void injectMembers(T task) {
                ((MGoBlogApplication) context.getApplicationContext())
                    .objectGraph().inject(task);
            }
        }
    
        public static class ServiceStarter<T extends Task> 
            implements ObjectQueue.Listener<T> {
    
            Context context;
            Class<? extends Service> service;
    
            /**
             * Starts the provided service when a Task is added to the queue
             *
             * @param context the application Context
             * @param service the Service to start
             */
            public ServiceStarter(Context context, 
                                  Class<? extends Service> service) {
                this.context = context;
                this.service = service;
            }
    
            @Override
            public void onAdd(ObjectQueue<T> queue, T entry) {
                context.startService(new Intent(context, service));
    
            }
    
            @Override
            public void onRemove(ObjectQueue<T> queue) {
            }
        }
    
    
        @Provides
        @Singleton
        TaskQueue<NodeIndexTask> provideNodeIndexTaskQueue() {
            ObjectQueue<NodeIndexTask> delegate = 
                new InMemoryObjectQueue<NodeIndexTask>();
            TaskQueue<NodeIndexTask> queue = new TaskQueue<NodeIndexTask>(
                delegate, new IOTaskInjector<NodeIndexTask>(appContext));
            queue.setListener(new ServiceStarter<NodeIndexTask>(
                appContext, NodeIndexTaskService.class));
            return queue;
        }
    
        @Provides
        @Singleton
        TaskQueue<NodeTask> provideNodeTaskQueue() {
            ObjectQueue<NodeTask> delegate = 
                new InMemoryObjectQueue<NodeTask>();
            TaskQueue<NodeTask> queue = new TaskQueue<NodeTask>(
                delegate, new IOTaskInjector<NodeTask>(appContext));
            queue.setListener(new ServiceStarter<NodeTask>(
                appContext, NodeTaskService.class));
            return queue;
        }
    }
    

    /**
     * Module that includes all of the app's modules. Used by Dagger
     * for compile time validation of injections and modules.
     */
    @Module(
            includes = {
                    MGoBlogAPIModule.class,
                    OttoModule.class,
                    TaskQueueModule.class
            }
    )
    public class MGoBlogAppModule {
    }
    

    Related posts:

    Why PNG compression is that much slower than JPEG on Android?
    Android material chips
    Android: Sleep stages/levels on an Android device?
    How to convert a Bitmap to Drawable in android?
    How to provide custom animation during sorting (notifyDataSetChanged) on RecyclerView
    Getting Started with WiFi on Android
  • jQuery's ajax function does not work in Android PhoneGap application
  • Getting Robolectric to work with Volley
  • OnLongItemClick in RecyclerView
  • RxJava + Retrofit -> BaseObservable for API calls for centralized response handling
  • How to implement 3-way conference call video chat with WebRTC Native Code for Android?
  • Handling different screen resolutions for background images in Android
  • One Solution collect form web for “Dagger can't find injectable members on a module”

    Dagger’s full graph analysis works from a complete module. i.e. @Module(complete = true), which is the default. Because it’s the default, dagger will, by default, assume that all bindings are available from that module or those modules it includes explicitly.

    In this case, you’ve given two modules that you claim are complete, but Dagger has no way to tie these together at compile time without an additional signal. In short, without OttoModule knowing about TaskQueueModule, the compiler will attempt to analyse OttoModule for its claimed completeness, and fail, because it doesn’t now about TaskQueueModule.

    Modify OttoModule’s annotation as such:

    @Module(
      includes = TaskQueueModule.class,
      entryPoints = {
        MGoBlogActivity.class,
        NodeFragment.class,
        NodeActivity.class,
        NodeCommentFragment.class,
        NodeIndexTaskService.class,
        NodeTaskService.class
      }
    )
    

    and then Dagger will know that for OttoModule to be complete, it includes the other module as part of its full definition.

    Note:dagger-compiler can’t detect that TaskQueueModule is there on the class path and just “know” that the developer intended it to be used with OttoModule without that additional signal. For instance, you might have several modules which define task queues and which one would it select? The declaration must be explicit.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.