Child Injector Eager Singletons?

71 views
Skip to first unread message

Sam Berlin

unread,
May 15, 2009, 6:47:23 PM5/15/09
to google...@googlegroups.com
Hi Folks,

Since upgrading to the latest snapshot, I'm trying to convert some code to use the newer features.  In attempting to use createChildInjector, it looks like the child injector doesn't eagerly create all singleton. I've included a test case for this at the end of the email.

We used to have a fake child-injector doing something like:

  Injector child = Guice.createInjector(Stage.PRODUCTION, providersFrom(parent), new OtherModules());

where providersFrom was:

        public static Module providersFrom(final Injector parent) {
            return new Module() {
                public void configure(Binder binder) {
                    Key loggerKey = Key.get(Logger.class);
                    Key injectorKey = Key.get(Injector.class);
                    Key stageKey = Key.get(Stage.class);
                   
                    for(Map.Entry<Key<?>, Binding<?>> entry : parent.getBindings().entrySet()) {
                        Key key = entry.getKey();
                        Binding binding = entry.getValue();
                        if(!key.equals(loggerKey) && !key.equals(injectorKey) && !key.equals(stageKey)) {
                            binder.bind(key).toProvider(binding.getProvider());
                        }
                    }
                   
                }
            };
        }

I'm converting this to a proper parent/child relationship using:

 Injector child = parent.createChildInjector(new OtherModules());

In order to test the old code worked properly, we had a test that created a parent module in Stage.PRODUCTION and the fake child module in Stage.PRODUCTION, and asserted that each singleton was properly eagerly created.  Since converting to using createChildInjector (and modifying the test to using createChildInjector), it doesn't look like singletons are being eagerly created anymore in the child.

The test is:

  public class ModulesTest extends TestCase {

    public void testChildEagerSingletons() {
        Injector parent = Guice.createInjector(Stage.PRODUCTION, new AbstractModule() {
            @Override
            protected void configure() {
                bind(S1.class).to(S1I.class);
            }
        });
        Injector child = parent.createChildInjector(new AbstractModule() {
            @Override
            protected void configure() {
                bind(S2.class).to(S2I.class);
                bind(S3I.class);
            }
        });
       
        assertTrue(S1I.created);
        assertSame(parent.getInstance(S1.class), child.getInstance(S1.class));
       
        assertTrue(S2I.created);
        assertTrue(S3I.created);
    }

    private static interface S1 {}
    @Singleton
    private static class S1I implements S1 {
        private static boolean created = false;
        S1I () { created = true; }
    }
    private static interface S2 {}
    @Singleton
    private static class S2I implements S2 {
        private static boolean created = false;
        S2I () { created = true; }
    }
    @Singleton
    private static class S3I {
        private static boolean created = false;
        S3I () { created = true; }
    }
 }

The assertTrue(S2I.created); fails.

Is this a bug, or expected behavior, or should I be doing something else?

Thanks!

Sam

limpb...@gmail.com

unread,
May 16, 2009, 1:00:59 PM5/16/09
to google-guice
Hey Sam, yeah sorry about this. It comes as a consequence of using
regular Guice stuff to create instances. I've added a note to the
docs.
http://tinyurl.com/pn4uca

If there's any other doc that could be improved, please let me know!
Or submit patches!

Sam Berlin

unread,
May 16, 2009, 2:36:33 PM5/16/09
to google...@googlegroups.com, google-guice
Did you mean to reply with this in the other thread (about @nullable)?

Any insight into this child injector eager singleton issue? The
@nullable one can be worked around, but I don't see a good way to
workaround this.

Sam

On May 16, 2009, at 1:00 PM, "je...@swank.ca" <limpb...@gmail.com>
wrote:

Alen Vrecko

unread,
May 16, 2009, 7:01:08 PM5/16/09
to google-guice
I've debugged a little bit. It is cool to see the inner workings of
Guice. It looks like:

The createChildInjector's injector JIT bindings end up at the root
injector (which is already fully "initialized" and is not
"reinitialized") therefore the bindings just sit there and don't get
processed. Probably better if they'd wind up at the child injector
like it happens with PrivateModules or something.

Probably the easiest if just use explicit bindings instead of
@Singleton.

Cheers,
Alen

On May 16, 8:36 pm, Sam Berlin <sber...@gmail.com> wrote:
> Did you mean to reply with this in the other thread (about @nullable)?
>
> Any insight into this child injector eager singleton issue?  The  
> @nullable  one can be worked around, but I don't see a good way to  
> workaround this.
>
> Sam
>
> On May 16, 2009, at 1:00 PM, "je...@swank.ca" <limpbiz...@gmail.com>  

Alen Vrecko

unread,
May 16, 2009, 7:09:48 PM5/16/09
to google-guice
Forgot to mention

bind(S2.class).to(S2I.class); // the S2I "JIT" ends up at parent
bind(S3I.class); // the S3I "JIT" ends up at child as expected

Cheers,
Alen

Sam Berlin

unread,
May 18, 2009, 9:13:24 PM5/18/09
to google...@googlegroups.com
I created issue 373 @ http://code.google.com/p/google-guice/issues/detail?id=373 for tracking this issue.

Sam
Reply all
Reply to author
Forward
0 new messages