Skip to content
This repository has been archived by the owner on Jan 31, 2019. It is now read-only.

Guice binding annotations not working #34

Open
mumrah opened this issue Nov 25, 2015 · 10 comments
Open

Guice binding annotations not working #34

mumrah opened this issue Nov 25, 2015 · 10 comments

Comments

@mumrah
Copy link

mumrah commented Nov 25, 2015

Copied from a Guice issue I previously filed (and closed): google/guice#966 (comment)

I have two modules that bind a set of strings like:

In FooModule:

Multibinder<String> fooThingsBinder = Multibinder.newSetBinder(binder(), String.class, Foo.class);
...
for(String foo: fooThings) {
  fooThingsBinder.addBinding().toInstance(foo);
}

And something similar in BarModule. Then elsewhere in the code I get these sets injected like:

public class FooResource(@Foo Set<String> fooThings, ...) { ... }

and something similar in BarResource.

What I'm seeing is that one of these sets non-deterministically gets injected to both resource classes. E.g., the foo things end up in FooResource and BarResource, or vice-versa.

I have tried using the @Named binding annotation as well, with the same results. I have another multi-binding that uses different types instead binding annotations, and it is working fine.

I'll try to come up with a test case later today/this week as time allows. I've worked around this for now by creating separate sub-types for the foo/bar things.

@rkapsi
Copy link
Contributor

rkapsi commented Nov 25, 2015

@mumrah: Do you have FooResource and BarResource bound in Guice?

@Override
protected void configure() {
  bind(FooResource.class);
  bind(BarResource.class);
}

I wonder if one of the resources is being initialized by HK2.

@stevesea
Copy link

stevesea commented Dec 8, 2015

I'm seeing what might a similar issue -- intermittently an incorrect binding is injected into a resource. (generally, I have to restart my application to get different behavior)

I'm trying to inject a JDBI DBI object into my resource. I have two annotated bindings for DBI Providers in my injector, one for a persistent database (@DbPersist), another for a in-memory database (@DbMem)


@Path("/mypath")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class MyResource {
    private final DBI dbi;
    @Inject
    public StoragePortResource(@DbMem DBI dbi) {
        this.dbi = dbi;
    }
}

Most of the time, the correct DBI is injected. Intermittently the wrong DBI is injected.

my stack: Dropwizard 0.8.5, dropwizard-guice 0.8.4, jersey2-guice 0.10, guice 4.0

I can debug where my DBI provider is being called, and from the callstack it looks like the call from jersey into the GuiceServiceLocator knows the source annotation on the constructor (@DbMem). But, 16+ calls later the call from GuiceBindingDescriptor into the Guice injector is asked for the DBI with the wrong binding annotation (@DbPersist)

(continued spelunking)

looking at it further... it seems like maybe it's happening during reflection, trying to get the constructor's parameters qualifiers...

(more spelunking)

in hk2-locator(2.4.0-b31), method
org.jvnet.hk2.internal.Utilities#getConstructorInjectees is called, and has my @DbMem annotation as a paramAnnotation. It calls getParamInformation(paramAnnotation), and returns an empty set for the qualifiers.

(additional spelunking)
and that investigation led me to this bug: #22

I'm still not sure why it sometimes works, and sometimes doesn't.

Adding @qualifier to my @DbMem / @DbPersist annotations appears to make my resource behave consistently.

@chriskessel
Copy link

chriskessel commented Sep 9, 2016

I'm having a very similar issue. I have two @provides for the same class, both with a custom annotation. So one @provides @foo, the other @provides @bar. The providers are in different modules, but both modules are part of the same application.

However, sometimes it injects @bar where @foo is specified in the constructor! It's random and unpredictable. It's driving me crazy. I'm having to wrap things in small unique classes to get things to work. Near as I can tell, custom bindings are broken or have some race condition.

@bar
Copy link

bar commented Sep 9, 2016

@chriskessel I don't think anyone is injecting me :/

@jylin
Copy link

jylin commented Oct 12, 2016

I'm seeing the same issue. I have an object annotated with @Named, and I get an instance of a random type each time. Also if I do @Named("something_i_didnt_bind"), it still gives me an instance, though random as well. Normally, that should throw an exception because I didn't bind anything with that name.

@chriskessel
Copy link

@jylin Are you using Dropwizard and Guice? I created this issue with the dropwizard-guice library, which is where the problem seems to lie, I think...
HubSpot/dropwizard-guice#91

@bar
Copy link

bar commented Oct 12, 2016

@chriskessel uhh?

@jylin
Copy link

jylin commented Oct 12, 2016

@chriskessel No, I'm not using any framework. I just have a main function that initializes guice, jersey and this bridge.

@jylin
Copy link

jylin commented Oct 13, 2016

I switched to using HK2 guice-bridge, and that seems to support Named injections better (though not perfect).

@tusharbhasme
Copy link

I am experiencing a very similar issue. I have a module that binds various BindingAnnotations with string values. In a jersey module, I am injecting one of those BindingAnnotations. Each time I start the server, in jersey module, I am getting any of the values from the various BindingAnnotation at random. These BindingAnnotations work fine in other modules of the application. It's just the jersey module that's facing this issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants