Hi,
I just did a quick test throwing the runtime SecurtyException as in
your example and verified that it gets passed to the Servlet container
(in GF v3 at least no stack trace is presented to the user).
When i threw a checked exception, say IOException, a
MappableContainerException, (of the cause IOException), gets passed to
the Servlet container.
So if you are not using an exception mapper it should be possible to
react to both runtime and checked exceptions in the servlet layer.
In your web.xml i think the following is incorrect:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/ejbException.jsp</location>
</error-page>
because a 404 will be returned. You will need to place that under the
jsp directory. I verified that i can do this can get error pages
called for java.lang.Exception and
com.sun.jersey.api.container.MappableContainerException, or just for
java.lang.Throwable.
There are cases when Jersey will send out the stack trace with a 500
response. That is something we can fix, but not in the time-frame you
require.
But, i think there may be a possible solution for certain cases (see
later). That is to write a ContainerResponseFilter to check for a 500
status code and to remove the entity.
package foo;
public class HackFilter implements ContainerResponseFilter {
public ContainerResponse filter(ContainerRequest request,
ContainerResponse response) {
if (response.getStatus() == 500) {
response.setEntity(null);
response.getHttpHeaders().put("Content-Type", null);
}
return response;
}
}
In your web.xml you can register that filter:
<init-param>
<param-
name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>foo.HackFilter</param-value>
</init-param>
The cases where this will work is when any response filters before
HackFilter throw an exception. Or when an exception occurs when
writing out the response entity.
Hope this helps,
Paul.
On Oct 14, 2009, at 9:53 AM, Jordi Domingo wrote:
> Good morning Paul,
>
> Did you get a solution for this? We are going to publish the site
> very soon (tomorrow) and we are focused on security so dumping full
> stack trace is not very secure :)
>
> Thanks again,
>
> Jordi
>
> Date: Mon, 5 Oct 2009 14:54:12 +0200
> From: Paul.Sandoz_at_Sun.COM
> To: users_at_jersey.dev.java.net
> Subject: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable
>
> DOH! i should read the email more carefully. Extracted successfully.
>
> Paul.
>
>
> On Oct 5, 2009, at 2:39 PM, Paul Sandoz wrote:
>
> Thanks, this is most helpful.
>
> I tried to unrar and it is complaining that a password is required.
> Looks like it might be an issue with the rar app i am using on the
> mac.
>
> UNRAR 3.60 beta 6 freeware Copyright (c) 1993-2006 Alexander
> Roshal
>
> Enter password (will not be echoed) for RestTest.rar:
>
> Encrypted file: CRC failed in /Users/paulsandoz/Downloads/
> RestTest.rar (password incorrect ?)
> No files to extract
>
> I am a bit busy this week with Java EE stuff, so i am unlikely to
> get time to look at this in detail until next week. Hope things are
> not so urgent that it can wait until then.
>
>
> FWIW i think there is a bug in Jersey and any
> MappedContainerException passed to the ServletContainer should re-
> throw the ServletException with the cause set to what was mapped.
>
> Paul.
>
> On Oct 2, 2009, at 6:03 PM, Jordi Domingo wrote:
>
> I made a very simple example, just a resource that throws a
> SecurityException without anything else. Its not maven, i dont use
> it :(
> I also added a system out of the media type, i get null again
> (resource has a Produces annotation)
>
> I uploaded the file to rapidshare, the password is jersey. http://rapidshare.com/files/287805087/RestTest.rar.html
>
> Thanks,
>
> Jordi
>
> P.D.
> The stacktrace of the example is:
>
> javax.ejb.EJBException
> at
> com
> .sun
> .ejb
> .containers.BaseContainer.processSystemException(BaseContainer.java:
> 4947)
> at
> com
> .sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:
> 4845)
> at
> com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:
> 4633)
> at
> com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:
> 1871)
> at
> com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:
> 1822)
> at
> com
> .sun
> .ejb
> .containers
> .EJBLocalObjectInvocationHandler
> .invoke(EJBLocalObjectInvocationHandler.java:198)
> at
> com
> .sun
> .ejb
> .containers
> .EJBLocalObjectInvocationHandlerDelegate
> .invoke(EJBLocalObjectInvocationHandlerDelegate.java:84)
> at $Proxy185.failMethod(Unknown Source)
> at
> com
> .domborjo
> .rest
> .__EJB31_Generated__TestResource__Intf____Bean__.failMethod(Unknown
> Source)
> 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
> $
> TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:
> 156)
> 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.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:724)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:689)
> at
> com
> .sun
> .jersey
> .server
> .impl
> .application
> .WebApplicationImpl.handleRequest(WebApplicationImpl.java:680)
> at
> com
> .sun
> .jersey.spi.container.servlet.WebComponent.service(WebComponent.java:
> 324)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.service(ServletContainer.java:425)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.doFilter(ServletContainer.java:
> 751)
> at
> com
> .sun
> .jersey
> .spi
> .container.servlet.ServletContainer.doFilter(ServletContainer.java:
> 703)
> 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:333)
> at
> org
> .apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
> 234)
> at
> com
> .sun
> .enterprise
> .v3.services.impl.ContainerMapper.service(ContainerMapper.java:146)
> at
> com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:
> 753)
> at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:
> 661)
> at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:914)
> at
> com
> .sun
> .grizzly
> .http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:166)
> 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.FixedThreadPool
> $BasicWorker.dowork(FixedThreadPool.java:379)
> at com.sun.grizzly.util.FixedThreadPool
> $BasicWorker.run(FixedThreadPool.java:360)
> at java.lang.Thread.run(Thread.java:619)
> Caused by: java.lang.SecurityException
> at com.domborjo.rest.TestResource.failMethod(TestResource.java:24)
> 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
> org
> .glassfish
> .ejb
> .security
> .application.EJBSecurityManager.runMethod(EJBSecurityManager.java:
> 1038)
> at
> org
> .glassfish
> .ejb
> .security
> .application.EJBSecurityManager.invoke(EJBSecurityManager.java:1110)
> at
> com
> .sun
> .ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:
> 5120)
> at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:610)
> at
> com
> .sun
> .ejb
> .containers
> .interceptors
> .AroundInvokeChainImpl.invokeNext(InterceptorManager.java:775)
> at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:562)
> at
> com
> .sun
> .ejb
> .containers
> .interceptors
> .SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:157)
> at
> com
> .sun
> .ejb
> .containers
> .interceptors
> .SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:139)
> 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
> .ejb
> .containers
> .interceptors
> .AroundInvokeInterceptor.intercept(InterceptorManager.java:836)
> at
> com
> .sun
> .ejb
> .containers
> .interceptors
> .AroundInvokeChainImpl.invokeNext(InterceptorManager.java:775)
> at
> com
> .sun
> .ejb
> .containers
> .interceptors.InterceptorManager.intercept(InterceptorManager.java:
> 349)
> at
> com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:
> 5092)
> at
> com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:
> 5080)
> at
> com
> .sun
> .ejb
> .containers
> .EJBLocalObjectInvocationHandler
> .invoke(EJBLocalObjectInvocationHandler.java:190)
> ... 45 more
>
>
> Date: Fri, 2 Oct 2009 17:23:42 +0200
> From: Paul.Sandoz_at_Sun.COM
> To: users_at_jersey.dev.java.net
> Subject: Re: [Jersey] ExceptionMapper and Viewable
>
>
> On Oct 2, 2009, at 5:10 PM, Jordi Domingo wrote:
>
> Hi again Paul!
>
> I saw that sometimes (to change behavior the server must be
> restarted) the exception goes through the mapper and sometimes not
> and it gets dumped. Maybe is a glassfish bug :S
>
> Quite possibly.
>
>
> In any case, do you know wich component may be dumping the exception
> (its an stacktrace like the one in glassfish logs).
>
> Can you send the stacktrace ?
>
>
> ----
>
> I tried using HttpContext:
>
> @Context HttpContext httpContext;
>
> And in the toResponse(..)
>
> MediaType m = httpContext.getResponse().getMediaType();
> MediaType selected = httpContext.getRequest().getMediaType();
>
> I get null.
>
> If "m" is null it implies that no resource method was called with
> @Produces.
>
> I think i would need to see more of your application to understand
> where the EJBException is originating from. In fact if you can send
> me a zip file of a maven project that would help.
>
> Recently i modified the behavior of processing EJBExcpetion such
> that Jersey registered a mapper for that class (see end of email).
> This is in 1.1.2. So actually EJBExcpetion will never be propagated
> to the Servlet container. Perhaps that is why things are not working
> for you. Note that you can override this with your own implementation.
>
> The mapper will attempt to extract the cause of the exception then
> attempt to map that.
>
> Does that give any more clues? as i said an example would help then
> i can debug it.
>
> Paul.
>
>
> public class EJBExceptionMapper implements
> ExceptionMapper<EJBException> {
>
> private final Providers providers;
>
> public EJBExceptionMapper(@Context Providers providers) {
> this.providers = providers;
> }
>
> public Response toResponse(EJBException exception) {
> final Exception cause = exception.getCausedByException();
> if (cause != null) {
> final ExceptionMapper mapper =
> providers.getExceptionMapper(cause.getClass());
> if (mapper != null) {
> return mapper.toResponse(cause);
> } else if (cause instanceof WebApplicationException) {
> return ((WebApplicationException)cause).getResponse();
> }
> }
>
> return Response.serverError().build();
> }
> }
>
>
>
> ---
> The first thing i tried was using the servlet exception rules (im
> using that yet with the mapper for EJBException) but happens the
> same with glassfish dumping the exception:
>
> <error-page>
> <exception-
> type>com.sun.jersey.api.container.MappableContainerException</
> exception-type>
> <location>/jsp/ejbException.jsp</location>
> </error-page>
> <error-page>
> <error-code>500</error-code>
> <location>/jsp/ejbException.jsp</location>
> </error-page>
>
> ---
> When a user sends a request, jersey selects wich method must attend
> the user and jersey know which one will be the response type by
> default. Is there any method for me, to know wich one will be?
> (httpContext.getResponse().getMediaType() returns null)
>
> Thanks Paul!
>
> > Date: Thu, 1 Oct 2009 10:33:48 +0200
> > From: Paul.Sandoz_at_Sun.COM
> > To: users_at_jersey.dev.java.net
> > Subject: Re: [Jersey] ExceptionMapper and Viewable
> >
> > On Sep 30, 2009, at 1:44 PM, Jordi Domingo wrote:
> >
> > >
> > > Hi :)
> > >
> > > I'm trying to make an ExceptionMapper that returns the response
> > > expected by the client. I dont know how i can return a Viewable
> or a
> > > JSON response because i dont have access to any object with that
> > > information
> > >
> > > public Response toResponse(EJBException exception) {}
> > >
> >
> > If a resource method was selected for invocation then the Content-
> Type
> > of the response will have been selected if the @Produces specifies a
> > concrete (non-wild card) media type. So if the Content-Type is
> present
> > you can look at that.
> >
> > You can inject Jersey's HttpContext on the ExceptionMapper and in
> the
> > toResponse method you can do:
> >
> > MediaType m = httpContext.getResponse().getMediaType();
> >
> > You can also get access to the acceptable headers by doing:
> >
> > httpContext.getRequest().getAcceptableMediaTypes()
> >
> > (That method is a method on javax.ws.rs.core.HttpHeaders, which
> can be
> > injected if required rather than referring to something Jersey
> > specific).
> >
> >
> > > On another side, when Jersey finds an Exception (not Runtime) that
> > > is not mapped, forwards it to the ServletContainer, thats fine.
> >
> > Any RuntimeException that is not mapped will be re-thrown and it
> will
> > pass through Jersey's Servlet layer to the Servlet framework from
> > where it can be mapped using Servlet-based rules.
> >
> > Any checked exception that is not mapped will be wrapped around a
> > Jersey runtime exception (ContainerException) and that will be
> passed
> > to Jersey's Servlet layer and wrapped in a ServletException
> exception
> > and re-thrown.
> >
> >
> > > When i do the same with an EJBException (SystemException) I dont
> > > know how to achieve the same behavior. This is my code for
> testing:
> > >
> > > public Response toResponse(EJBException exception) {
> > > final Exception cause = exception.getCausedByException();
> > >
> > > return new WebApplicationException(cause).getResponse();
> > > }
> > >
> >
> > I am not sure i understand what you want to achieve.
> >
> > Do you want the EJBException to be passed through to the Servlet
> > framework?
> >
> > Paul.
> >
> >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> > For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >
>
> Charlas más divertidas con el nuevo Windows Live Messenger
>
>
> Charlas más divertidas con el nuevo Windows Live Messenger
>
>
>
> Todo el espacio y cuidado que merecen tus fotos digitales lo tienes
> en Windows Live Fotos. ¡Pruébalo!