users@jersey.java.net

RE: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable

From: Jordi Domingo <noseya_at_hotmail.com>
Date: Thu, 15 Oct 2009 09:20:55 +0200

Hi Paul,

Thanks for your help. Your hack does his work, a NPE is generated then forwaded to the error page. Is there a way to recover the original exception?

On the other way, I dont understand why you get the SecurityException passed to the Servlet Container (im using GFv3 also). I followed your suggestions and simplified the jsp to its smallest form and it never gets passed without the hack, maybe I'm missing something.

Jordi

Date: Wed, 14 Oct 2009 12:32:16 +0200
From: Paul.Sandoz_at_Sun.COM
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable

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!
 		 	   		  
_________________________________________________________________
¿Sabías que ahora puedes hablar por Messenger desde Hotmail con todos tus contactos? Revisa tu correo mientras conversas con tus amigos. 
http://www.hotmail.com 
--_cddf3523-1062-4a80-ba7f-dea5222391da_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
Hi Paul,<br><br>Thanks for your help. Your hack does his work, a NPE is generated then forwaded to the error page. Is there a way to recover the original exception?<br><br>On the other way, I dont understand why you get the SecurityException passed to the Servlet Container (im using GFv3 also). I followed your suggestions and simplified the jsp to its smallest form and it never gets passed without the hack, maybe I'm missing something.<br><br>Jordi<br><br><hr id="stopSpelling">Date: Wed, 14 Oct 2009 12:32:16 +0200<br>From: Paul.Sandoz@Sun.COM<br>To: users@jersey.dev.java.net<br>Subject: Re: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable<br><br>Hi,<div><br></div><div>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).</div><div><br></div><div>When i threw a checked exception, say IOException, a MappableContainerException, (of the cause IOException), gets passed to the Servlet container.</div><div><br></div><div>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.&nbsp;</div><div><br></div><div>In your web.xml i think the following is incorrect:</div><div><br></div><div><div>&nbsp;&nbsp;&lt;error-page&gt;</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;exception-type&gt;java.lang.Throwable&lt;/exception-type&gt;</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;location&gt;/ejbException.jsp&lt;/location&gt;</div><div>&nbsp;&nbsp;&lt;/error-page&gt;</div><div><br></div><div>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&nbsp;com.sun.jersey.api.container.MappableContainerException, or just for java.lang.Throwable.</div></div><div><br></div><div><br></div><div>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.</div><div><br></div><div>But,&nbsp;i&nbsp;think&nbsp;there&nbsp;may&nbsp;be&nbsp;a&nbsp;possible&nbsp;solution&nbsp;for&nbsp;certain&nbsp;cases (see later). That is to write a ContainerResponseFilter to check for a 500 status code and to remove the entity.</div><div><br></div><div>&nbsp;&nbsp; &nbsp;package foo;</div><div><div>&nbsp;&nbsp; &nbsp;public class HackFilter implements ContainerResponseFilter {</div><div><br></div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (response.getStatus() == 500) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;response.setEntity(null);</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;response.getHttpHeaders().put("Content-Type", null);</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return response;</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div>&nbsp;&nbsp; &nbsp;}</div></div><div><br></div><div><br></div><div>In your web.xml you can register that filter:</div><div><br></div><div><pre>     &lt;init-param&gt;<br>         &lt;param-name&gt;com.sun.jersey.spi.container.ContainerResponseFilters&lt;/param-name&gt;<br>         &lt;param-value&gt;foo.HackFilter&lt;/param-value&gt;<br>     &lt;/init-param&gt;<br></pre></div><div><br></div><div>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&nbsp;entity.</div><div><br></div><div>Hope this helps,</div><div>Paul.</div><div><br></div><div><div><div>On Oct 14, 2009, at 9:53 AM, Jordi Domingo wrote:</div><br class="ecxApple-interchange-newline"><blockquote><div class="ecxhmmessage" style="font-size: 10pt; font-family: Verdana;">Good morning Paul,<br><br>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 :)<br><br>Thanks again,<br><br>Jordi<br><br><hr id="ecxstopSpelling">Date: Mon, 5 Oct 2009 14:54:12 +0200<br>From:<span class="ecxApple-converted-space">&nbsp;</span><a href="mailto:Paul.Sandoz@Sun.COM">Paul.Sandoz@Sun.COM</a><br>To:<span class="ecxApple-converted-space">&nbsp;</span><a href="mailto:users@jersey.dev.java.net">users@jersey.dev.java.net</a><br>Subject: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable<br><br>DOH! i should read the email more carefully. Extracted successfully.<div><br></div><div>Paul.<br><div><br></div><div><br><div><div>On Oct 5, 2009, at 2:39 PM, Paul Sandoz wrote:</div><br class="ecxecxApple-interchange-newline"><blockquote><div style="word-wrap: break-word;">Thanks, this is most helpful.<div><br></div><div>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.</div><div><br></div><div><div style="margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal;">&nbsp;&nbsp;UNRAR 3.60 beta 6 freeware&nbsp; &nbsp; &nbsp; Copyright (c) 1993-2006 Alexander Roshal</div><div style="margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; min-height: 14px;"><br></div><div style="margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal;">&nbsp;&nbsp;Enter password (will not be echoed) for RestTest.rar:&nbsp;</div><div style="margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal; min-height: 14px;"><br></div><div style="margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal;">&nbsp;&nbsp;Encrypted file:&nbsp; CRC failed in /Users/paulsandoz/Downloads/RestTest.rar (password incorrect ?)</div><div style="margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; font-size: 12px; line-height: normal;">&nbsp;&nbsp;No files to extract</div><div><br></div></div><div>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.</div><div><br></div><div><br></div><div>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.</div><div><br></div><div>Paul.</div><div><br></div><div><div><div>On Oct 2, 2009, at 6:03 PM, Jordi Domingo wrote:</div><br class="ecxecxApple-interchange-newline"><blockquote><div class="ecxecxhmmessage" style="font-size: 10pt; font-family: Verdana;">I made a very simple example, just a resource that throws a SecurityException without anything else. Its not maven, i dont use it :(<br>I also added a system out of the media type, i get null again (resource has a Produces annotation)<br><br>I uploaded the file to rapidshare, the password is jersey.<span class="ecxecxApple-converted-space">&nbsp;</span><a href="http://rapidshare.com/files/287805087/RestTest.rar.html">http://rapidshare.com/files/287805087/RestTest.rar.html</a><br><br>Thanks,<br><br>Jordi<span class="ecxecxApple-converted-space">&nbsp;</span><br><br>P.D.<br>The stacktrace of the example is:<br><br><pre>javax.ejb.EJBException<br>	at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:4947)<br>	at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:4845)<br>	at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4633)<br>	at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1871)<br>	at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1822)<br>	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:198)<br>	at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:84)<br>	at $Proxy185.failMethod(Unknown Source)<br>	at com.domborjo.rest.__EJB31_Generated__TestResource__Intf____Bean__.failMethod(Unknown Source)<br>	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br>	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br>	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br>	at java.lang.reflect.Method.invoke(Method.java:597)<br>	at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:156)<br>	at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:67)<br>	at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:208)<br>	at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:75)<br>	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:115)<br>	at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:67)<br>	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:724)<br>	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:689)<br>	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:680)<br>	at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:324)<br>	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:425)<br>	at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:751)<br>	at com.sun.jersey.spi.container.servlet.ServletContainer.doFilter(ServletContainer.java:703)<br>	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)<br>	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)<br>	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)<br>	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)<br>	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)<br>	at com.sun.enterprise.<a href="http://web.WebPipeline.invoke">web.WebPipeline.invoke</a>(WebPipeline.java:97)<br>	at com.sun.enterprise.<a href="http://web.PESessionLockingStandardPipeline.invoke">web.PESessionLockingStandardPipeline.invoke</a>(PESessionLockingStandardPipeline.java:85)<br>	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)<br>	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:333)<br>	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:234)<br>	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:146)<br>	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:753)<br>	at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:661)<br>	at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:914)<br>	at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:166)<br>	at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)<br>	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)<br>	at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)<br>	at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)<br>	at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)<br>	at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)<br>	at com.sun.grizzly.ContextTask.run(ContextTask.java:69)<br>	at com.sun.grizzly.util.FixedThreadPool$BasicWorker.dowork(FixedThreadPool.java:379)<br>	at com.sun.grizzly.util.FixedThreadPool$BasicWorker.run(FixedThreadPool.java:360)<br>	at java.lang.Thread.run(Thread.java:619)<br>Caused by: java.lang.SecurityException<br>	at com.domborjo.rest.TestResource.failMethod(TestResource.java:24)<br>	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br>	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br>	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br>	at java.lang.reflect.Method.invoke(Method.java:597)<br>	at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1038)<br>	at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1110)<br>	at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5120)<br>	at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:610)<br>	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:775)<br>	at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:562)<br>	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:157)<br>	at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:139)<br>	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br>	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br>	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br>	at java.lang.reflect.Method.invoke(Method.java:597)<br>	at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:836)<br>	at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:775)<br>	at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:349)<br>	at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5092)<br>	at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5080)<br>	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:190)<br>	... 45 more<br></pre><br><br><hr id="ecxecxstopSpelling">Date: Fri, 2 Oct 2009 17:23:42 +0200<br>From:<span class="ecxecxApple-converted-space">&nbsp;</span><a href="mailto:Paul.Sandoz@Sun.COM">Paul.Sandoz@Sun.COM</a><br>To:<span class="ecxecxApple-converted-space">&nbsp;</span><a href="mailto:users@jersey.dev.java.net">users@jersey.dev.java.net</a><br>Subject: Re: [Jersey] ExceptionMapper and Viewable<br><br><br><div><div>On Oct 2, 2009, at 5:10 PM, Jordi Domingo wrote:</div><br class="ecxecxecxApple-interchange-newline"><blockquote><span class="ecxecxecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="ecxecxecxhmmessage" style="font-size: 10pt; font-family: Verdana;">Hi again Paul!<br><br>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</div></span></blockquote><div><br></div>Quite possibly.</div><div><br></div><div><br><blockquote><span class="ecxecxecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="ecxecxecxhmmessage" style="font-size: 10pt; font-family: Verdana;">In any case, do you know wich component may be dumping the exception (its an stacktrace like the one in glassfish logs).<br></div></span></blockquote><div><br></div>Can you send the stacktrace ?</div><div><br></div><div><br><blockquote><span class="ecxecxecxApple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;"><div class="ecxecxecxhmmessage" style="font-size: 10pt; font-family: Verdana;">----<br><br>I tried using HttpContext:<br><br>@Context HttpContext httpContext;<br><br>And in the toResponse(..)<br><br>MediaType m = httpContext.getResponse().getMediaType();<br>MediaType selected = httpContext.getRequest().getMediaType();<br><br>I get null.<span class="ecxecxecxApple-converted-space">&nbsp;</span><br></div></span></blockquote><div><br></div>If "m" is null it implies that no resource method was called with @Produces.</div><div><br></div><div>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.</div><div><br></div><div>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&nbsp;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.</div><div><br></div><div>The mapper will attempt to extract the cause of the exception then attempt to map that.</div><div><br></div><div>Does that give any more clues? as i said an example would help then i can debug it.</div><div><br></div><div>Paul.</div><div><br></div><div><br></div><div><div>public class EJBExceptionMapper implements ExceptionMapper&lt;EJBException&gt; {</div><div><br></div><div>&nbsp;&nbsp; &nbsp;private final Providers providers;</div><div><br></div><div>&nbsp;&nbsp; &nbsp;public EJBExceptionMapper(@Context Providers providers) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;this.providers = providers;</div><div>&nbsp;&nbsp; &nbsp;}</div><div><br></div><div>&nbsp;&nbsp; &nbsp;public Response toResponse(EJBException exception) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;final Exception cause = exception.getCausedByException();</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (cause != null) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;final ExceptionMapper mapper = providers.getExceptionMapper(cause.getClass());</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (mapper != null) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return mapper.toResponse(cause);</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} else if (cause instanceof WebApplicationException) {</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return ((WebApplicationException)cause).getResponse();</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div><br></div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return Response.serverError().build();</div><div>&nbsp;&nbsp; &nbsp;}</div><div>}</div><div><br></div></div><div><br></div><div><br><blockquote><div class="ecxecxecxhmmessage" style="font-size: 10pt; font-family: Verdana;">---<br>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:<br><br>&lt;error-page&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;exception-type&gt;com.sun.jersey.api.container.MappableContainerException&lt;/exception-type&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;location&gt;/jsp/ejbException.jsp&lt;/location&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/error-page&gt;<br>&nbsp;&nbsp;&nbsp; &lt;error-page&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;error-code&gt;500&lt;/error-code&gt;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;location&gt;/jsp/ejbException.jsp&lt;/location&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/error-page&gt;<br><br>---<br>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)<br><br>Thanks Paul!<br><br>&gt; Date: Thu, 1 Oct 2009 10:33:48 +0200<br>&gt; From:<span class="ecxecxecxApple-converted-space">&nbsp;</span><a href="mailto:Paul.Sandoz@Sun.COM">Paul.Sandoz@Sun.COM</a><br>&gt; To:<span class="ecxecxecxApple-converted-space">&nbsp;</span><a href="mailto:users@jersey.dev.java.net">users@jersey.dev.java.net</a><br>&gt; Subject: Re: [Jersey] ExceptionMapper and Viewable<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; On Sep 30, 2009, at 1:44 PM, Jordi Domingo wrote:<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; &gt;<br>&gt; &gt; Hi :)<br>&gt; &gt;<br>&gt; &gt; I'm trying to make an ExceptionMapper that returns the response<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; &gt; expected by the client. I dont know how i can return a Viewable or a<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; &gt; JSON response because i dont have access to any object with that<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; &gt; information<br>&gt; &gt;<br>&gt; &gt; public Response toResponse(EJBException exception) {}<br>&gt; &gt;<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; If a resource method was selected for invocation then the Content-Type<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; of the response will have been selected if the @Produces specifies a<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; concrete (non-wild card) media type. So if the Content-Type is present<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; you can look at that.<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; You can inject Jersey's HttpContext on the ExceptionMapper and in the<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; toResponse method you can do:<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; MediaType m = httpContext.getResponse().getMediaType();<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; You can also get access to the acceptable headers by doing:<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; httpContext.getRequest().getAcceptableMediaTypes()<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; (That method is a method on javax.ws.rs.core.HttpHeaders, which can be<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; injected if required rather than referring to something Jersey<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; specific).<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; &gt; On another side, when Jersey finds an Exception (not Runtime) that<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; &gt; is not mapped, forwards it to the ServletContainer, thats fine.<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; Any RuntimeException that is not mapped will be re-thrown and it will<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; pass through Jersey's Servlet layer to the Servlet framework from<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; where it can be mapped using Servlet-based rules.<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; Any checked exception that is not mapped will be wrapped around a<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; Jersey runtime exception (ContainerException) and that will be passed<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; to Jersey's Servlet layer and wrapped in a ServletException exception<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; and re-thrown.<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; &gt; When i do the same with an EJBException (SystemException) I dont<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; &gt; know how to achieve the same behavior. This is my code for testing:<br>&gt; &gt;<br>&gt; &gt; public Response toResponse(EJBException exception) {<br>&gt; &gt; final Exception cause = exception.getCausedByException();<br>&gt; &gt;<br>&gt; &gt; return new WebApplicationException(cause).getResponse();<br>&gt; &gt; }<br>&gt; &gt;<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; I am not sure i understand what you want to achieve.<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; Do you want the EJBException to be passed through to the Servlet<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; framework?<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; Paul.<br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br>&gt; ---------------------------------------------------------------------<br>&gt; To unsubscribe, e-mail:<span class="ecxecxecxApple-converted-space">&nbsp;</span><a href="mailto:users-unsubscribe@jersey.dev.java.net">users-unsubscribe@jersey.dev.java.net</a><br>&gt; For additional commands, e-mail:<span class="ecxecxecxApple-converted-space">&nbsp;</span><a href="mailto:users-help@jersey.dev.java.net">users-help@jersey.dev.java.net</a><br>&gt;<span class="ecxecxecxApple-converted-space">&nbsp;</span><br><br><hr>Charlas más divertidas con el nuevo<span class="ecxecxecxApple-converted-space">&nbsp;</span><a href="http://download.live.com">Windows Live Messenger</a></div></blockquote></div><br><br><hr>Charlas más divertidas con el nuevo<span class="ecxecxApple-converted-space">&nbsp;</span><a href="http://download.live.com">Windows Live Messenger</a></div></blockquote></div><br></div></div></blockquote></div><br></div></div><br><hr>Todo el espacio y cuidado que merecen tus fotos digitales lo tienes en Windows Live Fotos.<span class="ecxApple-converted-space">&nbsp;</span><a href="http://www.vivelive.com/compartirfotos/">¡Pruébalo!</a></div></blockquote></div><br></div> 		 	   		  <br /><hr />¿Para qué descargarte juegos, si tienes los más divertidos online?  <a href='http://juegosonline.es.msn.com/' target='_new'>Entra ya en Juegos y prepárate para muchas horas de diversión</a></body>
</html>
--_cddf3523-1062-4a80-ba7f-dea5222391da_--