users@jersey.java.net

RE: [Jersey] Problem with injected HttpServletRequest proxy

From: Ian Carr <Ian.Carr_at_focus-solutions.co.uk>
Date: Tue, 8 Dec 2009 12:36:08 +0000

Yep, good one, I had also left out the try catch in the handler I wrote in my Filter, adding it in the behavior is as expected!

I don't suppose that will make it into the GF release?, is there a way I can use an alternate implementation of Jersey from WEB-INF/lib?

Ian

-----Original Message-----
From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
Sent: 08 December 2009 12:23
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] Problem with injected HttpServletRequest proxy

I think i know what is going on.

I can reproduce with a very simple SE-based example (see end of email).

The problem is that the method.invoke is throwing an
InvocationTargetException that is passed back to the proxy and of
course InvocationTargetException is not declared as a checked
exception on the HttpServletRequest.login method.

This fix is to catch the InvocationTargetException and re-throw the
target exception.

Paul.

public class Main {

     public static class CheckedException extends Exception {}

     public static interface X {
         public String checked() throws CheckedException;

         public String runtime();
     }

     public static class IH implements InvocationHandler {
         private X x = new X() {

             public String checked() throws CheckedException {
                 throw new CheckedException();
             }

             public String runtime() {
                 throw new RuntimeException();
             }
         };

         public Object invoke(Object o, Method method, Object[] os)
throws Throwable {
             try {
                 return method.invoke(x, os);
             } catch (InvocationTargetException ex) {
                 throw ex.getTargetException();
             }
         }

     }

     /**
      * @param args the command line arguments
      */
     public static void main(String[] args) {
         new Main().test();
     }

     public void test() {
         X x = (X)Proxy.newProxyInstance(
                 this.getClass().getClassLoader(),
                 new Class[] { X.class },
                 new IH());

         try {
             x.checked();
         } catch (Exception e) {
             e.printStackTrace();
         }

         try {
             x.runtime();
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
}


On Dec 8, 2009, at 11:20 AM, Paul Sandoz wrote:

> On Dec 7, 2009, at 8:05 PM, Ian Carr wrote:
>
>> I have checked the objects in the cause list, and as far as my code
>> is concerned the ServletExceptions are instanceof the class as
>> exposed to my class, and they appear to be from a classloader with
>> the same hashCode as the one my class gets ServletException from.
>>
>
> OK, thanks for checking. I need to do the same investigations within
> the Jersey code, when the proxy is invoked.
>
> Paul.
>
>> Ian
>>
>> -----Original Message-----
>> From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
>> Sent: 07 December 2009 17:57
>> To: users_at_jersey.dev.java.net
>> Subject: Re: [Jersey] Problem with injected HttpServletRequest proxy
>>
>>
>> On Dec 7, 2009, at 6:46 PM, Ian Carr wrote:
>>
>>> Will do!
>>>
>>
>> Thanks!
>>
>>
>>> I have checked that I am not accidentally deploying anything I
>>> shouldn't and as far as I can tell, the WEB-INF lib of my project is
>>> clean.
>>>
>>
>> OK.
>>
>>
>>> I can add a reflection test elsewhere in the app (in a filter) to
>>> examine the login method signature and let you know the results.
>>>
>>
>> Yes, that is a good idea.
>>
>>
>>> I assume the proxy is created on the fly based on the implementation
>>> in the application classpath?
>>>
>>
>> It is created at servlet initialization time as follows:
>>
>> rc.getSingletons().add(new
>> ContextInjectableProvider<HttpServletRequest>(
>> HttpServletRequest.class,
>> (HttpServletRequest)Proxy.newProxyInstance(
>> this.getClass().getClassLoader(),
>> new Class[] { HttpServletRequest.class },
>> requestInvoker)));
>>
>> Paul.
>>
>>> Ian
>>>
>>> -----Original Message-----
>>> From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
>>> Sent: 07 December 2009 16:02
>>> To: users_at_jersey.dev.java.net
>>> Subject: Re: [Jersey] Problem with injected HttpServletRequest proxy
>>>
>>> Hi Ian,
>>>
>>> Could you log an issue?
>>>
>>> I am not sure why the proxying is not working. The JavaDoc of
>>> UndeclaredThrowableException [1] states:
>>>
>>> Thrown by a method invocation on a proxy instance if its invocation
>>> handler's invoke method throws a checked exception (a
>>> Throwable that is not assignable to RuntimeException or Error) that
>>> is not assignable to any of the exception types declared
>>> in the throws clause of the method that was invoked on the proxy
>>> instance and dispatched to the invocation handler.
>>>
>>> As i understand that can only happen if the HttpServletRequest class
>>> that is proxied has a login method that does not declare that it
>>> throws ServletException. So i am wondering how that can be the
>>> case. I
>>> am guessing this is a new case because AFAICT previously Servlet did
>>> not have any checked exceptions on HttpServletRequest methods.
>>>
>>> As work around you can inject:
>>>
>>> @Context ThreadLocal<HttpServletRequest> req
>>>
>>> Paul.
>>>
>>> [1] http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/UndeclaredThrowableException.html
>>>
>>> On Dec 7, 2009, at 4:11 PM, Ian Carr wrote:
>>>
>>>> Hi, I am working with glassfish v3 build 74 and trying to
>>>> experiment
>>>> with the new Servlet 3.0 login and logout methods from jersey.
>>>>
>>>> I am injecting the HttpServletRequest into one of my Jersey methods
>>>> and
>>>> invoking the login method, if the user id and password map then all
>>>> is OK. However if the login method throws it's ServletException as
>>>> documented (bad username/password or other issue) I get a stack
>>>> trace
>>>> which seems to indicate that the, presumably generated, injected
>>>> proxy
>>>> ($Proxy153) is not expecting the ServletException
>>>> (java.lang.reflect.UndeclaredThrowableException)
>>>>
>>>> Not sure if this is relevant but the class is also using the JCDI
>>>> injection mechanism and is annotated as an @ManagedBean.
>>>>
>>>> Method:
>>>>
>>>> @POST
>>>> @Path("login")
>>>> @Consumes( { MediaType.APPLICATION_JSON })
>>>> public void loginUser(@Context HttpServletRequest req, UIdent
>>>> ident) {
>>>> try {
>>>> // does the login work?
>>>> String uname = ident.getUname();
>>>> String pword = ident.getPword();
>>>> req.login(uname, pword);
>>>> } catch (ServletException ex) {
>>>> __log.info("Failed login attempt", ex);
>>>> throw new WebApplicationException(Status.UNAUTHORIZED);
>>>> }
>>>> }
>>>>
>>>> Stack trace:
>>>>
>>>> [#|2009-12-07T14:58:37.252+0000|WARNING|glassfishv3.0|
>>>> javax.enterprise.system.container.web.com.sun.enterprise.web|
>>>> _ThreadID=24;_ThreadName=http-thread-pool-8080-(1);|
>>>> StandardWrapperValve[default]:
>>>> PWC1406: Servlet.service() for servlet default threw exception
>>>> java.lang.reflect.UndeclaredThrowableException
>>>> at $Proxy153.login(Unknown Source)
>>>> at imc.test.resource.MainResource.loginUser(MainResource.java:121)
>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> at
>>>> sun
>>>> .reflect
>>>> .NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>> at
>>>> sun
>>>> .reflect
>>>> .DelegatingMethodAccessorImpl
>>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl.model.method.dispatch.AbstractResourceMethodDispatchProvider
>>>> $
>>>> VoidOutInvoker
>>>> ._dispatch(AbstractResourceMethodDispatchProvider.java:
>>>> 139)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl
>>>> .model
>>>> .method
>>>> .dispatch
>>>> .ResourceJavaMethodDispatcher
>>>> .dispatch(ResourceJavaMethodDispatcher.java:67)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:
>>>> 208)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:
>>>> 115)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:75)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:
>>>> 115)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl
>>>> .uri
>>>> .rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:
>>>> 67)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl
>>>> .application
>>>> .WebApplicationImpl._handleRequest(WebApplicationImpl.java:775)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl
>>>> .application
>>>> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:740)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl
>>>> .application
>>>> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:731)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .spi.container.servlet.WebComponent.service(WebComponent.java:
>>>> 372)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .spi
>>>> .container.servlet.ServletContainer.service(ServletContainer.java:
>>>> 452)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .spi
>>>> .container.servlet.ServletContainer.doFilter(ServletContainer.java:
>>>> 780)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .spi
>>>> .container.servlet.ServletContainer.doFilter(ServletContainer.java:
>>>> 732)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina
>>>> .core
>>>> .ApplicationFilterChain
>>>> .internalDoFilter(ApplicationFilterChain.java:
>>>> 256)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina
>>>> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
>>>> 215)
>>>> at imc.test.util.AcceptFilter.doFilter(AcceptFilter.java:65)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina
>>>> .core
>>>> .ApplicationFilterChain
>>>> .internalDoFilter(ApplicationFilterChain.java:
>>>> 256)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina
>>>> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
>>>> 215)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina
>>>> .core.StandardWrapperValve.invoke(StandardWrapperValve.java:
>>>> 277)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina
>>>> .core.StandardContextValve.invoke(StandardContextValve.java:
>>>> 188)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina.core.StandardPipeline.invoke(StandardPipeline.java:
>>>> 641)
>>>> at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
>>>> at
>>>> com
>>>> .sun
>>>> .enterprise
>>>> .web
>>>> .PESessionLockingStandardPipeline
>>>> .invoke(PESessionLockingStandardPipeline.java:85)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
>>>> at
>>>> org
>>>> .apache
>>>> .catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
>>>> 233)
>>>> at
>>>> com
>>>> .sun
>>>> .enterprise
>>>> .v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
>>>> at
>>>> com
>>>> .sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:
>>>> 791)
>>>> at
>>>> com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:
>>>> 693)
>>>> at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:
>>>> 954)
>>>> at
>>>> com
>>>> .sun
>>>> .grizzly
>>>> .http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
>>>> at
>>>> com
>>>> .sun
>>>> .grizzly
>>>> .DefaultProtocolChain
>>>> .executeProtocolFilter(DefaultProtocolChain.java:135)
>>>> at
>>>> com
>>>> .sun
>>>> .grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:
>>>> 102)
>>>> at
>>>> com
>>>> .sun
>>>> .grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:
>>>> 88)
>>>> at
>>>> com
>>>> .sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:
>>>> 76)
>>>> at
>>>> com
>>>> .sun
>>>> .grizzly
>>>> .ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
>>>> at
>>>> com
>>>> .sun
>>>> .grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:
>>>> 57)
>>>> at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
>>>> at
>>>> com.sun.grizzly.util.AbstractThreadPool
>>>> $Worker.doWork(AbstractThreadPool.java:330)
>>>> at
>>>> com.sun.grizzly.util.AbstractThreadPool
>>>> $Worker.run(AbstractThreadPool.java:309)
>>>> at java.lang.Thread.run(Thread.java:619)
>>>> Caused by: java.lang.reflect.InvocationTargetException
>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> at
>>>> sun
>>>> .reflect
>>>> .NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>> at
>>>> sun
>>>> .reflect
>>>> .DelegatingMethodAccessorImpl
>>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .server
>>>> .impl
>>>> .container
>>>> .servlet.ThreadLocalInvoker.invoke(ThreadLocalInvoker.java:
>>>> 90)
>>>> ... 48 more
>>>> Caused by: javax.servlet.ServletException: Exception thrown while
>>>> attempting to authenticate for user: test
>>>> at org.apache.catalina.connector.Request.login(Request.java:1921)
>>>> at
>>>> org
>>>> .apache.catalina.connector.RequestFacade.login(RequestFacade.java:
>>>> 1145)
>>>> ... 53 more
>>>> Caused by: javax.servlet.ServletException: Failed login while
>>>> attempting
>>>> to authenticate user: test
>>>> at org.apache.catalina.connector.Request.login(Request.java:1913)
>>>> ... 54 more
>>>>
>>>> Any ideas?
>>>>
>>>> Many thanks
>>>>
>>>> Ian
>>>>
>>>> ---------------------------------------------------------------------
>>>> 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
>>>
>>>
>>> ---------------------------------------------------------------------
>>> 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
>>
>>
>> ---------------------------------------------------------------------
>> 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
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
For additional commands, e-mail: users-help_at_jersey.dev.java.net