Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding annotations aren't being consistently honored #91

Open
chriskessel opened this issue Sep 9, 2016 · 3 comments
Open

Binding annotations aren't being consistently honored #91

chriskessel opened this issue Sep 9, 2016 · 3 comments

Comments

@chriskessel
Copy link

I tried to file this with Guice, but they won't look at it because I'm using Dropwizard, so maybe this is the right place?

I have two modules, each provides an instance of the same class (a specific Gson configuration). So, each module has a method like so:

@Provides
@ModuleA (this is @ModuleB in the other module)
public Gson provideGson() { ... }

Then I have constructors for classes that use those Gson items, that look like:

@Inject
public FooBar(@ModuleA gson) { ... }

This does NOT work consistently. Sometimes it injects the @moduleb version of Gson into things annotationed with @ModuleA.

I'm using Dropwizard 0.8.5 with dropwizard-guice 0.8.4 and Guice 4.1.

@jhaber
Copy link
Member

jhaber commented Sep 9, 2016

Do you have an example I can use to reproduce this?

@chriskessel
Copy link
Author

No, I'll have to work on one. And since it's non-deterministic, I'm not sure what part of the complexity of my current setup might be related.

@chriskessel
Copy link
Author

Ok, I think I have a stand alone test. I ran this, hit both endpoints:

http://localhost:8080/a/foo
http://localhost:8080/b/foo

In my log output, I can see:

INFO  [2016-09-13 19:49:38,180] org.eclipse.jetty.server.Server: Started @3827ms
I'm A and I got: module a
127.0.0.1 - - [13/Sep/2016:19:52:06 +0000] "GET /a/foo HTTP/1.1" 200 - "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36" 70
I'm B and I got: module a
127.0.0.1 - - [13/Sep/2016:19:52:09 +0000] "GET /b/foo HTTP/1.1" 200 - "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36" 5

As you can see, the ModuleBApi got injected with the wrong string despite the binding annotation. Unless I'm doing something wrong with annotations?

I crammed everything into one file, so hopefully this is easy for you to test:

package com.kessel.test;

import com.codahale.metrics.annotation.ExceptionMetered;
import com.codahale.metrics.annotation.Timed;
import com.google.inject.AbstractModule;
import com.google.inject.BindingAnnotation;
import com.google.inject.Provides;
import com.google.inject.Stage;
import com.hubspot.dropwizard.guice.GuiceBundle;
import io.dropwizard.Application;
import io.dropwizard.Configuration;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;


public class TestMain extends Application<TestMain.TestConfig> {

    public static void main(String... args) throws Exception {
        new TestMain().run(args);
    }

    public void initialize(Bootstrap<TestConfig> bootstrap) {
        GuiceBundle.Builder<TestConfig> guiceBundleBuilder = GuiceBundle.newBuilder();
        guiceBundleBuilder.addModule(new GuiceModuleA());
        guiceBundleBuilder.addModule(new GuiceModuleB());
        GuiceBundle<TestConfig> guiceBundle = guiceBundleBuilder.enableAutoConfig(getAutoConfigPackages()).build(Stage.DEVELOPMENT);
        bootstrap.addBundle(guiceBundle);
    }

    protected String[] getAutoConfigPackages() {
        return new String[]{this.getClass().getPackage().getName()};
    }

    public void run(TestConfig config, Environment environment) throws Exception {
    }

    public static class TestConfig extends Configuration {
    }

    public static class GuiceModuleA extends AbstractModule {

        @Override
        protected void configure() {
        }

        @Provides
        @Singleton
        @ModuleA
        public String provideModuleAString() {
            return "module a";
        }

        @BindingAnnotation
        @Target({FIELD, PARAMETER, METHOD})
        @Retention(RUNTIME)
        public @interface ModuleA {
        }
    }

    public static class GuiceModuleB extends AbstractModule {

        @Override
        protected void configure() {
        }

        @Provides
        @Singleton
        @ModuleB
        public String provideModuleString() {
            return "module b";
        }

        @BindingAnnotation
        @Target({FIELD, PARAMETER, METHOD})
        @Retention(RUNTIME)
        public @interface ModuleB {
        }
    }

    @Path("/a")
    public static class ModuleAApi {

        @Inject
        public ModuleAApi(@GuiceModuleA.ModuleA String injectableThing) {
            System.out.println("I'm A and I got: " + injectableThing);
        }

        @GET
        @Timed
        @ExceptionMetered
        @Path("foo")
        public Response foo() {
            return Response.ok().build();
        }
    }

    @Path("/b")
    public static class ModuleBApi {

        @Inject
        public ModuleBApi(@GuiceModuleB.ModuleB String injectableThing) {
            System.out.println("I'm B and I got: " + injectableThing);
        }

        @GET
        @Timed
        @ExceptionMetered
        @Path("foo")
        public Response foo() {
            return Response.ok().build();
        }
    }
}

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

No branches or pull requests

2 participants