dev@jersey.java.net

GuiceComponentProviderFactory seems to eagerly support resources that are not explicitly bound in the given Injector.

From: Jae Lee <jlee119_at_gmail.com>
Date: Wed, 23 Sep 2009 01:12:24 +0100

Hi all,

I've came across the problem with GuiceComponentProviderFactory, when there
are multiple of those registered in IoCResourceFactory.
GuiceComponentProviderFactory will always support any resource classes that
are not explicitly bound in the Injector that the ProviderFactory is
constructed with, resulting in the first GuiceComponentProviderFactory will
always be used to construct any resource.

I've got two resources that are managed by two different Injectors, and thus
two different GuiceComponentProviderFactories. However when
IoCResourceFactory is constructed with those two
GuiceComponentProviderFactories it always use the first one to construct any
resources. And the test fails...

any thought?

public class GuiceComponentProviderFactoryForMultipleInjectorsTest {
    public static interface Message {}

    public static class HelloWorld implements Message {}

    public static class HelloMe implements Message {}

    @Path("mail/world")
    public static class MailWorld {
        private Message message;

        @Inject
        public MailWorld(Message message) {
            this.message = message;
        }
    }

    @Path("mail/me")
    public static class MailMe {
        private Message message;

        @Inject
        public MailMe(Message message) {
            this.message = message;
        }
    }

    private ResourceFactory buildResourceFactory(Injector... injectors) {
        ResourceConfig resourceConfig = new DefaultResourceConfig();

        List<IoCComponentProviderFactory> factories = new
ArrayList<IoCComponentProviderFactory>();
        for(Injector injector : injectors) {
            factories.add(new GuiceComponentProviderFactory(resourceConfig,
injector));
        }

        return new IoCResourceFactory(resourceConfig, new
ServerInjectableProviderFactory(), factories);
    }

    @Test
    public void shouldSupportMultipleInjectors() {
        Injector injector1 = Guice.createInjector(new AbstractModule(){
            @Override
            protected void configure() {
                bind(Message.class).to(HelloWorld.class);
                bind(MailWorld.class);
            }
        });

        Injector injector2 = Guice.createInjector(new AbstractModule(){
            @Override
            protected void configure() {
                bind(Message.class).to(HelloMe.class);
                bind(MailMe.class);
            }
        });

        HttpContext httpContext = mock(HttpContext.class);
        ResourceComponentProvider componentProvider =
buildResourceFactory(injector1,
injector2).getComponentProvider(MailWorld.class);
        componentProvider.init(new AbstractResource(MailWorld.class));


assertThat(((MailWorld)componentProvider.getInstance(httpContext)).message,
is(HelloWorld.class));

        componentProvider = buildResourceFactory(injector1,
injector2).getComponentProvider(MailMe.class);
        componentProvider.init(new AbstractResource(MailMe.class));


assertThat(((MailWorld)componentProvider.getInstance(httpContext)).message,
is(HelloMe.class));
    }
}