I am seeing conflicting behavior between Jetty and Grizzly. I assume
Grizzly also embeds servlet engine. The following code works in Jetty,
not in Grizzly. Remember this is not a singleton scenario.
@Path("perrequest/constructor")
public static class PerRequestConstructorResource {
String path;
HttpSession session;
public PerRequestConstructorResource(@Context HttpServletRequest req) {
path = req.getPathInfo();
session = req.getSession();
}
@Produces("text/plain")
@GET
public String get() {
System.out.println("Session new : " + session.isNew());
return path;
}
}
-Arul
Paul Sandoz wrote:
>
> 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.processRootResources(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
>