users@jersey.java.net

[Jersey] Re: Binding _at_RequestScoped data

From: cowwoc <cowwoc_at_bbs.darktech.org>
Date: Mon, 12 May 2014 20:56:12 -0400

Hi Robert,

I am trying to integrate Jersey with a 3rd-party IoC framework. I've got
a class MyRegistry that holds request-scoped values (e.g. a database
connection) which I don't want to bind to HK2 directly. Instead, I want
to inject MyRegistry into resources and use it to look up the
aforementioned values.

I bound MyRegistry to ServiceLocator using:

bindFactory(RequestFactory.class).to(MyRegistry.class).in(RequestScoped.class);

where RequestFactory.provide() invokes something along the lines of:

MyRegistry result = serviceLocator.getService(MyRegistry.class);
if (registry==null)
{
     MyRegistry result =new MyRegistry(serviceLocator);
     ServiceLocatorUtilities.bind(serviceLocator,
                 new PerRequestBinder<>(MyRegistry.class, result));
}

and PerRequestBinder was a Binder that invoked:

bindFactory(new MyFactory()).to(MyRegistry.class).in(RequestScoped.class);

and MyRegistry.provide() returned "result" passed into PerRequestBinder.

So to recap: I bound a preexisting Factory instance (not a class)
against a scope, and that factory returned a preexisting instance
(again, no construction is taking place). What I was seeing is that most
of the time "serviceLocator.getService(MyRegistry.class)" worked fine,
but sometimes it would return a non-null value even though the request
had no constructed a MyRegistry instance before. Further debugging
revealed that the instance being returned actually belonged to the
previous HTTP request and was coming from some sort of "cache" in
ServiceLocatorImpl.

Any ideas?

Gili

On 12/05/2014 7:49 PM, Robert DiFalco wrote:
> What are you binding to? I mean isn't @RequestScoped meant for your
> resource? Meaning it will be re-instantiated for each request? It
> looks like you are trying to overload what it is used for in some way.
>
> Are you saying that you are @RequestScoped annotating your REST
> resource and that you sometimes see it not being instantiated for a
> request?
>
> Also, just wondering, what is the high level problem you are trying to
> solve? Maybe there is a better way of solving the problem that does
> not involve @RequestScoped.
>
>
>
> On Mon, May 12, 2014 at 4:41 PM, cowwoc <cowwoc_at_bbs.darktech.org
> <mailto:cowwoc_at_bbs.darktech.org>> wrote:
>
> Hi,
>
> How are we supposed to bind @RequestScoped variables in Jersey?
>
> 1. The scope @RequestScoped is listed in Jersey's "internal" package.
> 2. When I try to bindFactory().in(RequestScoped.class) I
> sometimes get stale values out of ServiceLocator.getService().
> Meaning, the Factory binding is not getting removed at the end
> of the HTTP request.
> 3. Using ThreadLocal doesn't seem safe in light of the fact that
> threads could be reused across HTTP requests, and there
> doesn't seem to be a clean way to detect the end of a request.
>
>
> Any ideas?
>
> Thanks,
> Gili
>
>