users@jersey.java.net

Re: [Jersey] issue with SingletonConstructorResource ?

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 22 Aug 2008 22:35:39 +0200

On Aug 22, 2008, at 10:23 PM, Arul Dhesiaseelan wrote:

> Paul,
>
> Thanks for the clarification.
>
> I was not able to test SingletonConstructorResource scenario in 0.8
> and I thought the fix you made for this would work in 0.9.
>
> So, is this a valid scenario?
>
> @Path("singleton/constructor")
> @Singleton
> public static class SingletonConstructorResource {
> @Context HttpServletRequest r;
>
> public SingletonConstructorResource(@Context
> HttpServletRequest r) {
> this.r = r;
> r.getSession().setAttribute("test", "true");
> ==============================> is it illegal to call this method?

Yes, it is illegal, if the resource class is constructed before a
valid HTTP request, which is currently the case. I think i might be
able to fix this. Namely construction of the singleton should occur
when needed and not when initialized, then you will have access to
the request in which the resource was created.


> }
>
> @Produces("text/plain")
> @GET public String get() {
> return (String)r.getAttribute("test");
> }
> }
>
> I have a requirement to set some params in session when the
> resource is first created. Is there any other way to do this?
>

Currently, i think you will need to work around it by performing
checks in the resource method. Namely use a boolean field and some
synchronized logic:

   synchronized(this) {
     if (!init) {
         init = true;
        // set up variable on session
     }
   }

Paul.

> Please look at the related thread on this issue: https://
> jersey.dev.java.net/servlets/BrowseList?
> list=users&by=thread&from=1188713
>
> Thanks!
> Arul
>
> Paul Sandoz wrote:
>> Hi Arul,
>>
>> I just tested on 0.9 and 0.10 with the Grizzly Web container and
>> the all the servlet artifacts are non-null and are injected for
>> all the variations that you present below.
>>
>> However, i was wondering how your code worked at all in 0.8. The
>> reason is the a singleton is created out of the scope of an HTTP
>> request. Thus you should not be able to call methods on the
>> HttpServlerRequest instance because there is no actual request
>> instance set (underneath the covers thread local proxy is used). I
>> should really be throwing an IllegalStateException for these cases.
>>
>> Paul.
>>
>> On Aug 22, 2008, at 6:44 PM, Arul Dhesiaseelan wrote:
>>
>>> Hi Paul,
>>>
>>> I am still having issue with constructor injection in singleton
>>> resources in Jersey 0.9. If I comment
>>> SingletonConstructorResource in the below code, I can run other 3
>>> scenarios just fine which was working fine in 0.8 too. If I
>>> uncomment SingletonConstructorResource, then none of the
>>> scenarios work in 0.9. Am I missing something? I remember you had
>>> fixed this issue earlier.
>>>
>>> I am getting the following exception when trying to invoke any of
>>> the resources:
>>>
>>> com.sun.jersey.api.container.ContainerException: Unable to create
>>> resource
>>> at com.sun.jersey.impl.resource.SingletonProvider.init
>>> (SingletonProvider.java:88)
>>> at
>>> com.sun.jersey.spi.resource.ResourceProviderFactory.createProvider
>>> (ResourceProviderFactory.java:132)
>>> at com.sun.jersey.impl.model.ResourceClass.init
>>> (ResourceClass.java:180)
>>> at
>>> com.sun.jersey.impl.application.WebApplicationImpl.getResourceClass(
>>> WebApplicationImpl.java:267)
>>> at
>>> com.sun.jersey.impl.application.WebApplicationImpl.processRootResour
>>> ces(WebApplicationImpl.java:796)
>>> at com.sun.jersey.impl.application.WebApplicationImpl.initiate
>>> (WebApplicationImpl.java:668)
>>> at com.sun.jersey.impl.application.WebApplicationImpl.initiate
>>> (WebApplicationImpl.java:485)
>>> at
>>> com.sun.jersey.spi.container.servlet.ServletContainer.initiate
>>> (ServletContainer.java:559)
>>> at com.sun.jersey.spi.container.servlet.ServletContainer.load
>>> (ServletContainer.java:483)
>>> at com.sun.jersey.spi.container.servlet.ServletContainer.init
>>> (ServletContainer.java:165)
>>> at org.mortbay.jetty.servlet.ServletHolder.initServlet
>>> (ServletHolder.java:433)
>>> at org.mortbay.jetty.servlet.ServletHolder.getServlet
>>> (ServletHolder.java:342)
>>> at org.mortbay.jetty.servlet.ServletHolder.handle
>>> (ServletHolder.java:463)
>>> at org.mortbay.jetty.servlet.ServletHandler.handle
>>> (ServletHandler.java:362)
>>> at org.mortbay.jetty.servlet.SessionHandler.handle
>>> (SessionHandler.java:181)
>>> at org.mortbay.jetty.handler.ContextHandler.handle
>>> (ContextHandler.java:729)
>>> at org.mortbay.jetty.handler.HandlerWrapper.handle
>>> (HandlerWrapper.java:152)
>>> at org.mortbay.jetty.Server.handle(Server.java:324)
>>> at org.mortbay.jetty.HttpConnection.handleRequest
>>> (HttpConnection.java:505)
>>> at org.mortbay.jetty.HttpConnection
>>> $RequestHandler.headerComplete(HttpConnection.java:829)
>>> at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:513)
>>> at org.mortbay.jetty.HttpParser.parseAvailable
>>> (HttpParser.java:211)
>>> at org.mortbay.jetty.HttpConnection.handle
>>> (HttpConnection.java:380)
>>> at org.mortbay.jetty.bio.SocketConnector$Connection.run
>>> (SocketConnector.java:228)
>>> at org.mortbay.thread.QueuedThreadPool$PoolThread.run
>>> (QueuedThreadPool.java:488)
>>> Caused by: java.lang.reflect.InvocationTargetException
>>> at sun.reflect.NativeConstructorAccessorImpl.newInstance0
>>> (Native Method)
>>> at sun.reflect.NativeConstructorAccessorImpl.newInstance
>>> (NativeConstructorAccessorImpl.java:39)
>>> at sun.reflect.DelegatingConstructorAccessorImpl.newInstance
>>> (DelegatingConstructorAccessorImpl.java:27)
>>> at java.lang.reflect.Constructor.newInstance(Constructor.java:
>>> 494)
>>> at com.sun.jersey.impl.application.WebApplicationImpl
>>> $DefaultResourceComponentProvider.getInstance
>>> (WebApplicationImpl.java:465)
>>> at com.sun.jersey.impl.resource.SingletonProvider.init
>>> (SingletonProvider.java:84)
>>> ... 24 more
>>> Caused by: java.lang.NullPointerException
>>> at jersey.Inject$SingletonConstructorResource.(Inject.java:42)
>>> ... 30 more
>>>
>>>
>>>
>>>
>>> public class Inject {
>>> @Path("singleton")
>>> @Singleton
>>> public static class SingletonResource {
>>> @Context
>>> HttpServletRequest r;
>>>
>>> @Produces("text/plain")
>>> @GET
>>> public String get() {
>>> return r.getPathInfo();
>>> }
>>> }
>>>
>>> // @Path("singleton/constructor")
>>> // @Singleton
>>> // public static class SingletonConstructorResource {
>>> // @Context HttpServletRequest r;
>>> //
>>> // public SingletonConstructorResource(@Context
>>> HttpServletRequest r) {
>>> // this.r = r;
>>> // r.getSession().setAttribute("test", "true");
>>> // }
>>> //
>>> // @Produces("text/plain")
>>> // @GET public String get() {
>>> // return (String)r.getAttribute("test");
>>> // }
>>> // }
>>>
>>> @Path("perrequest")
>>> public static class PerRequestResource {
>>> @Context
>>> HttpServletRequest r;
>>>
>>> @Produces("text/plain")
>>> @GET
>>> public String get() {
>>> return r.getPathInfo();
>>> }
>>> }
>>>
>>> @Path("perrequest/constructor")
>>> public static class PerRequestConstructorResource {
>>> String path;
>>>
>>> public PerRequestConstructorResource(@Context
>>> HttpServletRequest r) {
>>> path = r.getPathInfo();
>>> }
>>>
>>> @Produces("text/plain")
>>> @GET
>>> public String get() {
>>> return path;
>>> }
>>> }
>>>
>>> public static void main(String[] args) throws Exception {
>>> ServletHolder sh = new ServletHolder(ServletContainer.class);
>>> sh.setInitParameter("com.sun.jersey.config.property.packages",
>>> "jersey");
>>> Server server = new Server(9999);
>>> org.mortbay.jetty.servlet.Context context = new
>>> org.mortbay.jetty.servlet.Context(server, "/",
>>> org.mortbay.jetty.servlet.Context.SESSIONS);
>>> context.addServlet(sh, "/*");
>>> server.start();
>>> }
>>>
>>> }
>>>
>>> Thanks!
>>> Arul
>>>
>>>
>>> --------------------------------------------------------------------
>>> -
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>> ________________________________
>> Scanned by MessageLabs for Flux
>> ________________________________
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>