question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Non-static providers inside abstract modules cause runtime crashes

See original GitHub issue

If you forget to add static to an abstract module your app will crash at runtime. This should be prevented at compile time.

Example: Suppose you have a nice abstract module such as the following example:

class SomeOuterClass {
  @dagger.Module
  public abstract static class Module {
      @NonNull
      @OnlineScope
      @Provides
      static A a() {
          return new A();
      }
  }

  @OnlineScope
  @dagger.Component(modules = Module.class, dependencies = ParentComponent.class)
  interface Component {
      @dagger.Component.Builder
      interface Builder {
          @BindsInstance
          Builder interactor(OnlineInteractor interactor);

          @BindsInstance
          Builder view(Observable<Optional<OnlineView>> view);

          Builder parentComponent(ParentComponent component);
          Component build();
      }
  }
}

Next, lets add a new provider to the Module.

@dagger.Module
public abstract static class Module {
    @NonNull
    @OnlineScope
    @Provides
    static A a() {
        return new A();
       }
   }

    @NonNull
    @OnlineScope
    @Provides
    B b() {
        return new B();
    }
}

Oops! We forgot to add static to the second provider. This example now crashes at runtime.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:4
  • Comments:12

github_iconTop GitHub Comments

7reactions
pyricaucommented, Aug 7, 2017

We’ve been running into the same issue. Technically, this is actually not a Dagger bug. However this behavior leads to incorrect usage.

There are 3 kind of modules:

  • Modules for which Dagger needs instances, and can create on its own:
@Module
class MyModule {
  @Provides Thing foo() { return new Thing(); }
}
  • Modules for which Dagger does not need instances:
@Module
abstract class MyModule {
  @Provides static Thing foo() { return new Thing(); }
}
  • Modules for which Dagger needs instances, but cannot create on its own:
@Module
class MyModule {
  Thing thing;

  MyModule(Thing thing) { this.thing = thing; }

  @Provides Thing foo() { return thing; }
}

For the latter modules, the build() method of Builders will throw an exception if a module instance has not been set manually on the component builder.

The problem appears with this type of module:

@Module
abstract class MyModule {
  @Provides static Thing foo() { return new Thing(); }

  @Provides OtherThing bar() { return new OtherThing(); }
}

This latter module has a second method that isn’t static. So Dagger needs a module instance. However that module is abstract and therefore Dagger cannot create instances. So the generated code expects the module instance to be provided.

This case could maybe be a compiler error instead. However, there might be legitimate cases for abstract modules with real implementations that aren’t known to Dagger.

2reactions
ronshapirocommented, Aug 11, 2017

I talked this over with @netdpb and we think the best path forward is to not allow abstract modules that have instance @Provides methods. The error will say to either make the methods static, or use a subclass of the module (where it’s clear whether or not an instance is required). How does that sound?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Abstract method error runtime crash - java - Stack Overflow
I'm developer and game developers use my library in their apps only a single developer reported a runtime Abstract method error crash issue ......
Read more >
Chapter 13. Binary Compatibility - Oracle Help Center
Deleting a class member or constructor that is not declared private may cause a linkage error if the member or constructor is used...
Read more >
Java - Washington
// the following assignment passes type checking at compile time, // but will cause a runtime exception: p_array [1] = new Point(); //...
Read more >
Contexts and Dependency Injection - Quarkus
Annotate the bean with @io.quarkus.runtime. ... it is possible that a removal results in a false positive error, i.e. a bean ... Provider...
Read more >
Bug listing with status RESOLVED with resolution OBSOLETE ...
... with error message" status:RESOLVED resolution:OBSOLETE severity:normal ... Bug:111388 - "pyfest ebuild-- python module for festival" status:RESOLVED ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found