users@jersey.java.net

[Jersey] Re: Binding _at_RequestScoped data

From: cowwoc <cowwoc_at_bbs.darktech.org>
Date: Mon, 12 May 2014 21:53:03 -0400

Right, this is similar to what I'm doing, except I need it to be request
scoped ;)

Any ideas on why it's the latter is not working?

Gili

On 12/05/2014 9:04 PM, Robert DiFalco wrote:
> I do this too I just do it a little differently, I do this in my config:
>
> register(new AbstractBinder() {
> @Override
> protected void configure() {
> bind(new MyServiceRegistryImpl()).to(MyServiceRegistry.class);
> }
> });
>
> Then in my resource I just do this:
>
>
> @Singleton
> public class UserResource {
>
> private final UserService userService;
>
> @Inject
> public UserResource(MyServiceRegistry registry) {
> this.userService = registry.getService(UserService.class);
> }
>
>
>
> There's not a lot of magic going on so it makes it super easy to debug.
>
> R.
>
>
>
> On Mon, May 12, 2014 at 5:56 PM, cowwoc <cowwoc_at_bbs.darktech.org
> <mailto:cowwoc_at_bbs.darktech.org>> wrote:
>
> 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
>>
>>
>
>