Cool,
In your GuiceChildParentNoScopeSingletonTest, does ResourceContext represent
a request scope? (i.e. each subsequent request will get different instance
of ResourceContext).
1. testNoScope reads like for 'NO_SCOPE', you get new instance of
resource every time requested in a given request.
2. testSingleton reads like for 'SINGLETON', you get the same instance of
resource every time requested in a given request.
3. Can I assume that it will work the same way in other scenarios?
In the same session, you will get new instance of resource for 'NO_SCOPE'.
In a different request, you will get the same instance of resource for
'SINGLETON'
It's been very helpful to get this resolved.
Thanks Paul,
J
On Wed, May 13, 2009 at 4:24 PM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
> Hi,
> On May 13, 2009, at 1:44 AM, Jae Lee wrote:
>
> Hi Paul,
>
> I made some attempts on writing some tests for the scenarios that I
> described...
>
> Through some debugging the tests that I've written, I've learned a bit more
> about Jersey, where for explicit Guice bound object it's mapping
>
> 1. Scopes.SINGLETON ----> ComponentScope.Singleton
> 2. Scopes.NO_SCOPE ----> ComponentScope.PerRequest
>
> Yes. Plus:
>
> com.google.inject.servlet.RequestScoped -> ComponentScope.PerRequest
>
> if using the ServletModule.
>
>
> It was a bit of surprise that (if my test is written correct... I need some
> confirmation on whether I'm building ResourceFactory in the right way and
> also the way I'm modeling multiple Resource instantiation in the same
> request and different requests is reasonable)
>
> 1. for objects in child injector; Scopes.NO_SCOPE, it seems to generate
> new instance in the same request
>
>
> Yes, because Jersey defers to Guice for instantiation. In this respect it
> just means that Jersey's Per request is compatible (i.e. wider) than Guices
> NO_SCOPE, so Jersey can inject per request resources.
>
>
> 1. for objects in parent injector; Scopes.NO_SCOPE, it seems to
> generate same instance in the same request
>
> I think this is because the bindings in the parent are not being traversed,
> so Jersey cannot find it in the child injector, and is deferring to Guice to
> instantiate an instance but Jersey is managing the life-cycle using
> the GuiceInstantiatedComponentProvider.
>
> Can you verify via the logs what component provider class is being used to
> manage BoundInParentInjector and BoundInChildInjector?
>
>
> 1. for objects in child/parent injector; Scopes.SINGLETON, it seems to
> generate same instance all the time
>
> For the parent object it should be the same as 2.
>
> For the child object that does make sense because it is a singleton.
>
>
> I am going to commit a fix, java.net SVN is down so i cannot do it at the
> moment, for traversing parent injectors. The fix includes a test based on
> your code.
>
> BTW i cannot hierarchical injectors to work with the ServletModel as a
> child. The bindings in the servlet module are not picked up so i am guessing
> the Injector injected into the Jersey GuiceContainter is the parent, which
> might be a bug.
>
> Paul.
>
>
> 1.
>
> Regards
> J
>
> On Mon, May 11, 2009 at 1:49 PM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>
>> Hi Jae,
>> BTW i am still finding my away around with Guice and am by no means an
>> expert so providing use cases like this is very valuable.
>>
>> I notice that from here:
>>
>>
>> http://code.google.com/p/google-guice/source/browse/trunk/src/com/google/inject/Injector.java
>>
>> /**
>> * Returns all explicit bindings.
>> *
>> * <p>The returned map does not include bindings inherited from a {_at_link
>> #getParent() parent
>> * injector}, should one exist. The returned map is guaranteed to
>> iterate (for example, with
>> * its {_at_link java.util.Map#entrySet()} iterator) in the order of
>> insertion. In other words,
>> * the order in which bindings appear in user Modules.
>> *
>> * <p>This method is part of the Guice SPI and is intended for use by
>> tools and extensions.
>> */
>> Map<Key<?>, Binding<?>> getBindings();
>>
>>
>> So the Injector.getBindings does not return bindings from the parent
>> injector (if any). It was not the intention to ignore bindings of the
>> parent.
>>
>> So IIUC the fix would be to traverse up the injector hierarchy, to find
>> the injector that contains an explicit binding for the class:
>>
>> private Injector findInjector(Key<?> key) {
>> Injector i = injector;
>> while (i != null) {
>> if (i.getBindings().containsKey(key))
>> return i;
>>
>> i = i.getParent();
>> }
>> return null;
>> }
>>
>> public IoCComponentProvider getComponentProvider(ComponentContext cc,
>> Class clazz) {
>> if (LOGGER.isLoggable(Level.FINE)) {
>> LOGGER.fine("getComponentProvider(" + clazz.getName() + ")");
>> }
>>
>> Key<?> key = Key.get(clazz);
>> Injector i = findInjector(key);
>> // If there is no explicit binding
>> if (i == null) {
>> // If an @Inject is explicitly declared
>> if (!isInjectPresent(clazz)) {
>> return null;
>> }
>> ...
>>
>>
>> Would that work for you?
>>
>> Would it be possible to provide a simple test case that represents your
>> use-case and i can add that as a unit test.
>>
>> Paul.
>>
>>
>> On May 10, 2009, at 2:23 PM, Jae Lee wrote:
>>
>> Hi all,
>> I've got a newbie question really...
>>
>> From brief look through GuiceComponentProviderFactory source code
>> (1.1.0.ea), it looks like if you built GuiceComponentProviderFactory with an
>> Injector Guice Scope is ignored for an object explicitly bound by its parent
>> Injector... is that an intended behaviour?
>>
>> In my current project, we've got an Application and many Components
>> underneath. Component being loosely related resources, defines an
>> independent context. It is achieved by having a child Injector for each
>> Component under an Application.
>>
>> Naturally we would have common class/object bound in Injector in
>> Application (a bit like application scope) and component specific
>> class/object bound in child Injector in Component (a bit like component
>> scope)
>>
>> It looks like GuiceComponentProviderFactory uses
>> GuiceInstantiatedComponentProvider which ignores Guice Scope, for any
>> explicitly bound class in parent Injector. Which is bit of problem when it
>> comes to Singleton scoped class.
>>
>> Injector.getBinding(key) does return binding from parent Injector if
>> possible then fall back to Just In Time binding with Scopes.NO_SCOPE.
>>
>> Given that even for Just In Time binding, there's a scope (NO_SCOPE) that
>> can be mapped to Jersey, is it possible to use GuiceManagedComponentProvider
>> all the time? Would that makes it functionally different from current
>> implementation? Benefit would be that then it can support Singleton Guice
>> object in parent Injector properly.
>>
>> regards
>> J
>>
>>
>>
> <GuiceComponentProviderFactoryTest.java>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: dev-help_at_jersey.dev.java.net
>
>
>