You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "Duncan Keysell (dkeysell)" <dk...@cisco.com> on 2012/11/02 13:13:15 UTC

Re: CXF 2.7.0 loosing original exception message after wrapping in WebApplicationException

Hi Sergey,

The temporary workaround is not working for me :-(. I am getting class
cast exception. This is because in my application I also have an exception:

public class XMPWebApplicationException extends WebApplicationException {
Š.
{

And a mapper for it:

public class XMPWebAppExceptionMapper implements
ExceptionMapper<XMPWebApplicationException> {
Š.
}

So with the workaround in JAXRSUtils.convertFaultToResponse(T ex, Message
inMessage) that is provided in 2.7.1-SNAPSHOT:

Again the mapper and the exception satisfy the if statement and so the
exception get changed to a javax.ws.rs.BadRequestException inside
getWebApplicationExceptionClass method but the mapper is still expecting
to receive a XMPWebApplicationException or a subclass. So this causes
class cast exception.



Thanks
Duncan








On 30/10/2012 13:47, "Sergey Beryozkin" <sb...@gmail.com> wrote:

>Hi Duncan
>
>On 30/10/12 11:16, Duncan Keysell (dkeysell) wrote:
>> Hi,
>>
>> Thanks for the update. I'm building my application against
>>2.7.1-SNAPSHOT
>> now so I can try out a fix once you've had a time to look at this :-).
>
>I've just committed a temporarily fix. I'm looking for the final
>confirmation on whether this mapping of base WebApplicationExceptions to
>WebApplicationException subclass mappers will be actually supported, if
>yes - then I will optimize the current solution, if not - I will revert
>to the original code - I'll keep you up to date
>
>Thanks for reporting this issue,
>
>Sergey
>
>>
>> Thanks
>> Duncan
>>
>> On 25/10/2012 18:15, "Sergey Beryozkin"<sb...@gmail.com>  wrote:
>>
>>> On 25/10/12 17:17, Sergey Beryozkin wrote:
>>>> Hi Duncan
>>>>
>>>> Thanks for the analysis, comments inline
>>>>
>>>> On 25/10/12 14:18, Duncan Keysell (dkeysell) wrote:
>>>>> Hi,
>>>>>
>>>>> In the application code for my REST service all the exceptions are
>>>>> wrapped in WebApplicationException and then thrown. I have a test
>>>>>case
>>>>> to check this is working and below is the resource called in that
>>>>>test
>>>>> case:
>>>>>
>>>>>
>>>>> @GET
>>>>>
>>>>> @Path("/plainBad")
>>>>>
>>>>> public MgmtResponse throwPlainException() throws Exception {
>>>>>
>>>>> throw new WebApplicationException(new Exception("Some lame
>>>>>message"));
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>> I have an exception mapper (implementation of
>>>>> ExceptionMapper<WebApplicationException>) that creates the Response.
>>>>> This Response contains the message from the original exception as
>>>>>well
>>>>> as the exception type, up until I have moved to use 2.7.0.
>>>>>
>>>>>
>>>>> This is due to a change in the JAXRSUtils.convertFaultToResponse(T,
>>>>> Message) message between 2.6.2 and 2.7.0.
>>>>>
>>>>>
>>>>> Previously the method was (line 1217):
>>>>>
>>>>>
>>>>> public static<T extends Throwable>  Response convertFaultToResponse(T
>>>>> ex, Message inMessage) {
>>>>>
>>>>>
>>>>>
>>>>> ExceptionMapper<T>  mapper =
>>>>>
>>>>>
>>>>> 
>>>>>ProviderFactory.getInstance(inMessage).createExceptionMapper(ex.getCla
>>>>>ss
>>>>> (),
>>>>> inMessage);
>>>>>
>>>>> if (mapper != null) {
>>>>>
>>>>> try {
>>>>>
>>>>> return mapper.toResponse(ex);
>>>>>
>>>>> } catch (Exception mapperEx) {
>>>>>
>>>>> mapperEx.printStackTrace();
>>>>>
>>>>> return Response.serverError().build();
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> return null;
>>>>>
>>>>>
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>> And now it is (line 1352):
>>>>>
>>>>>
>>>>> @SuppressWarnings("unchecked")
>>>>>
>>>>> public static<T extends Throwable>  Response convertFaultToResponse(T
>>>>> ex, Message inMessage) {
>>>>>
>>>>> ProviderFactory factory = ProviderFactory.getInstance(inMessage);
>>>>>
>>>>> ExceptionMapper<T>  mapper = factory.createExceptionMapper(ex,
>>>>> inMessage);
>>>>>
>>>>> if (mapper != null) {
>>>>>
>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>
>>>>> &&  mapper.getClass() != WebApplicationExceptionMapper.class) {
>>>>>
>>>>> WebApplicationException webEx = (WebApplicationException)ex;
>>>>>
>>>>> Class<?>  exceptionClass =
>>>>> getWebApplicationExceptionClass(webEx.getResponse(),
>>>>>
>>>>> WebApplicationException.class);
>>>>>
>>>>> if (exceptionClass != WebApplicationException.class) {
>>>>>
>>>>> try {
>>>>>
>>>>> Constructor<?>  ctr = exceptionClass.getConstructor(Response.class);
>>>>>
>>>>> ex = (T)ctr.newInstance(webEx.getResponse());
>>>>>
>>>>> } catch (Exception ex2) {
>>>>>
>>>>> ex2.printStackTrace();
>>>>>
>>>>> return Response.serverError().build();
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> try {
>>>>>
>>>>> return mapper.toResponse(ex);
>>>>>
>>>>> } catch (Exception mapperEx) {
>>>>>
>>>>> mapperEx.printStackTrace();
>>>>>
>>>>> return Response.serverError().build();
>>>>>
>>>>> } finally {
>>>>>
>>>>> factory.clearExceptionMapperProxies();
>>>>>
>>>>> }
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> return null;
>>>>>
>>>>>
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> So the problem is that the exception 'ex' and my 'mapper' pass the if
>>>>> statement (line 1356):
>>>>>
>>>>>
>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>
>>>>> &&  mapper.getClass() != WebApplicationExceptionMapper.class)
>>>>>
>>>>>
>>>>> And then the ex gets over written and I loose all the details that
>>>>>the
>>>>> original WebApplicationException was holding. Shouldn't the if
>>>>> statement be changed not to allow any mapping implementing
>>>>> ExceptionMapper<WebApplicationException>? Is there some workaround
>>>>>for
>>>>> this?
>>>>>
>>>> I'm going to work on test case shortly. The actual change was needed
>>>>to
>>>> get new JAX-RS 2.0 exceptions such as NotFoundException (alternative
>>>>to
>>>> new WebApplicationException(404)), etc, captured by existing
>>>> ExceptionMapper<WebApplicationException>  mappers if no a mapper like
>>>> ExceptionMapper<NotFoundException>  exists, but a regression has been
>>>> introduced.
>>>>
>>> It is the other way around, if we have
>>> ExceptionMapper<NotFoundException>  but the code has thrown "new
>>> WebApplicationException(404)" then NotFoundExceptionMapper should be
>>> chosen given that NotFoundException extends WebApplicationException.
>>>
>>> I can see that the exception is lost in all the cases where the origin
>>> ex is WebApplicationException and the mapper is not known to CXF, it is
>>> really to do with a wrong constructor check, still looking, but will
>>> likely fix early next week due to the long weekend coming in
>>>
>>> The tests  show that if you register say
>>> ExceptionMapper<InternalServerErrorException>  and throw
>>> InternalServerErrorException then no cause exception is lost, in
>>> meantime I'll have a look at the other cases
>>>
>>> Cheers, Sergey
>>>
>>>> The possible workarounds: provide
>>>>ExceptionMapper<ServerErrorException>
>>>> or extend CXF WebApplicationExceptionMapper. Another one is CXF
>>>>specific
>>>> and it is to register a custom CXF invoker which will get a chance to
>>>> capture the original WebApplicationException, I guess it should be the
>>>> last resort option, I'll provide more info if doing other exception
>>>> mappers won't help
>>>>
>>>> Thanks, Sergey
>>>>
>>>>
>>>>
>>>>>
>>>>>
>>>>> Thanks
>>>>>
>>>>> Duncan
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>> --
>>> Sergey Beryozkin
>>>
>>> Talend Community Coders
>>> http://coders.talend.com/
>>>
>>> Blog: http://sberyozkin.blogspot.com
>>


Re: CXF 2.7.0 loosing original exception message after wrapping in WebApplicationException

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Duncan
On 12/11/12 13:21, Duncan Keysell (dkeysell) wrote:
> Hi Sergey,
> Thanks everything is working fine with the latest 2.7.1-SNAPSHOT.
>
OK, thanks for the confirmation

Cheers, Sergey

> Thanks
> Duncan
>
> On 05/11/2012 10:39, "Sergey Beryozkin"<sb...@gmail.com>  wrote:
>
>> Hi,
>>
>> I've reverted to the original code, but also updated the RS code to
>> throw WAE subclasses where possible as per the spec, example,
>> NotFoundException will be thrown instead of
>> WebApplicationException(404), etc
>>
>> Thanks, Sergey
>>
>>
>> On 02/11/12 15:28, Sergey Beryozkin wrote:
>>> Hi Duncan
>>> On 02/11/12 12:13, Duncan Keysell (dkeysell) wrote:
>>>> Hi Sergey,
>>>>
>>>> The temporary workaround is not working for me :-(. I am getting class
>>>> cast exception. This is because in my application I also have an
>>>> exception:
>>>>
>>>> public class XMPWebApplicationException extends
>>>> WebApplicationException {
>>>> Š.
>>>> {
>>>>
>>>> And a mapper for it:
>>>>
>>>> public class XMPWebAppExceptionMapper implements
>>>> ExceptionMapper<XMPWebApplicationException>  {
>>>> Š.
>>>> }
>>>>
>>>> So with the workaround in JAXRSUtils.convertFaultToResponse(T ex,
>>>> Message
>>>> inMessage) that is provided in 2.7.1-SNAPSHOT:
>>>>
>>>> Again the mapper and the exception satisfy the if statement and so the
>>>> exception get changed to a javax.ws.rs.BadRequestException inside
>>>> getWebApplicationExceptionClass method but the mapper is still
>>>> expecting
>>>> to receive a XMPWebApplicationException or a subclass. So this causes
>>>> class cast exception.
>>>>
>>>
>>> I'm going to revert to the original code (the one that was there in
>>> 2.6.x) asap. It appears I've misinterpreted what exactly we've agreed to
>>> awhile back on the spec list re mapping WebApplicationExceptions on the
>>> server side.
>>>
>>> While I still think that there's a certain degree of ambiguity with
>>> application-thrown WebApplicationExceptions not being mapped to
>>> specialized WebApplicationException subclass mappers, example
>>> (WebApplicationException(404) ->  NotFoundException mapper), I'm going to
>>> drop this code and revert to the old one.
>>>
>>> Thanks for the patience
>>> Sergey
>>>
>>>>
>>>>
>>>> Thanks
>>>> Duncan
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On 30/10/2012 13:47, "Sergey Beryozkin"<sb...@gmail.com>  wrote:
>>>>
>>>>> Hi Duncan
>>>>>
>>>>> On 30/10/12 11:16, Duncan Keysell (dkeysell) wrote:
>>>>>> Hi,
>>>>>>
>>>>>> Thanks for the update. I'm building my application against
>>>>>> 2.7.1-SNAPSHOT
>>>>>> now so I can try out a fix once you've had a time to look at this
>>>>>> :-).
>>>>>
>>>>> I've just committed a temporarily fix. I'm looking for the final
>>>>> confirmation on whether this mapping of base WebApplicationExceptions
>>>>> to
>>>>> WebApplicationException subclass mappers will be actually supported,
>>>>> if
>>>>> yes - then I will optimize the current solution, if not - I will
>>>>> revert
>>>>> to the original code - I'll keep you up to date
>>>>>
>>>>> Thanks for reporting this issue,
>>>>>
>>>>> Sergey
>>>>>
>>>>>>
>>>>>> Thanks
>>>>>> Duncan
>>>>>>
>>>>>> On 25/10/2012 18:15, "Sergey Beryozkin"<sb...@gmail.com>  wrote:
>>>>>>
>>>>>>> On 25/10/12 17:17, Sergey Beryozkin wrote:
>>>>>>>> Hi Duncan
>>>>>>>>
>>>>>>>> Thanks for the analysis, comments inline
>>>>>>>>
>>>>>>>> On 25/10/12 14:18, Duncan Keysell (dkeysell) wrote:
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> In the application code for my REST service all the exceptions are
>>>>>>>>> wrapped in WebApplicationException and then thrown. I have a test
>>>>>>>>> case
>>>>>>>>> to check this is working and below is the resource called in that
>>>>>>>>> test
>>>>>>>>> case:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> @GET
>>>>>>>>>
>>>>>>>>> @Path("/plainBad")
>>>>>>>>>
>>>>>>>>> public MgmtResponse throwPlainException() throws Exception {
>>>>>>>>>
>>>>>>>>> throw new WebApplicationException(new Exception("Some lame
>>>>>>>>> message"));
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I have an exception mapper (implementation of
>>>>>>>>> ExceptionMapper<WebApplicationException>) that creates the
>>>>>>>>> Response.
>>>>>>>>> This Response contains the message from the original exception as
>>>>>>>>> well
>>>>>>>>> as the exception type, up until I have moved to use 2.7.0.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> This is due to a change in the
>>>>>>>>> JAXRSUtils.convertFaultToResponse(T,
>>>>>>>>> Message) message between 2.6.2 and 2.7.0.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Previously the method was (line 1217):
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> public static<T extends Throwable>  Response
>>>>>>>>> convertFaultToResponse(T
>>>>>>>>> ex, Message inMessage) {
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ExceptionMapper<T>  mapper =
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ProviderFactory.getInstance(inMessage).createExceptionMapper(ex.get
>>>>>>>>> Cla
>>>>>>>>>
>>>>>>>>> ss
>>>>>>>>> (),
>>>>>>>>> inMessage);
>>>>>>>>>
>>>>>>>>> if (mapper != null) {
>>>>>>>>>
>>>>>>>>> try {
>>>>>>>>>
>>>>>>>>> return mapper.toResponse(ex);
>>>>>>>>>
>>>>>>>>> } catch (Exception mapperEx) {
>>>>>>>>>
>>>>>>>>> mapperEx.printStackTrace();
>>>>>>>>>
>>>>>>>>> return Response.serverError().build();
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> return null;
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> And now it is (line 1352):
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> @SuppressWarnings("unchecked")
>>>>>>>>>
>>>>>>>>> public static<T extends Throwable>  Response
>>>>>>>>> convertFaultToResponse(T
>>>>>>>>> ex, Message inMessage) {
>>>>>>>>>
>>>>>>>>> ProviderFactory factory = ProviderFactory.getInstance(inMessage);
>>>>>>>>>
>>>>>>>>> ExceptionMapper<T>  mapper = factory.createExceptionMapper(ex,
>>>>>>>>> inMessage);
>>>>>>>>>
>>>>>>>>> if (mapper != null) {
>>>>>>>>>
>>>>>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>>>>>
>>>>>>>>> &&  mapper.getClass() != WebApplicationExceptionMapper.class) {
>>>>>>>>>
>>>>>>>>> WebApplicationException webEx = (WebApplicationException)ex;
>>>>>>>>>
>>>>>>>>> Class<?>  exceptionClass =
>>>>>>>>> getWebApplicationExceptionClass(webEx.getResponse(),
>>>>>>>>>
>>>>>>>>> WebApplicationException.class);
>>>>>>>>>
>>>>>>>>> if (exceptionClass != WebApplicationException.class) {
>>>>>>>>>
>>>>>>>>> try {
>>>>>>>>>
>>>>>>>>> Constructor<?>  ctr =
>>>>>>>>> exceptionClass.getConstructor(Response.class);
>>>>>>>>>
>>>>>>>>> ex = (T)ctr.newInstance(webEx.getResponse());
>>>>>>>>>
>>>>>>>>> } catch (Exception ex2) {
>>>>>>>>>
>>>>>>>>> ex2.printStackTrace();
>>>>>>>>>
>>>>>>>>> return Response.serverError().build();
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> try {
>>>>>>>>>
>>>>>>>>> return mapper.toResponse(ex);
>>>>>>>>>
>>>>>>>>> } catch (Exception mapperEx) {
>>>>>>>>>
>>>>>>>>> mapperEx.printStackTrace();
>>>>>>>>>
>>>>>>>>> return Response.serverError().build();
>>>>>>>>>
>>>>>>>>> } finally {
>>>>>>>>>
>>>>>>>>> factory.clearExceptionMapperProxies();
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> return null;
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> So the problem is that the exception 'ex' and my 'mapper' pass
>>>>>>>>> the if
>>>>>>>>> statement (line 1356):
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>>>>>
>>>>>>>>> &&  mapper.getClass() != WebApplicationExceptionMapper.class)
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> And then the ex gets over written and I loose all the details that
>>>>>>>>> the
>>>>>>>>> original WebApplicationException was holding. Shouldn't the if
>>>>>>>>> statement be changed not to allow any mapping implementing
>>>>>>>>> ExceptionMapper<WebApplicationException>? Is there some workaround
>>>>>>>>> for
>>>>>>>>> this?
>>>>>>>>>
>>>>>>>> I'm going to work on test case shortly. The actual change was
>>>>>>>> needed
>>>>>>>> to
>>>>>>>> get new JAX-RS 2.0 exceptions such as NotFoundException
>>>>>>>> (alternative
>>>>>>>> to
>>>>>>>> new WebApplicationException(404)), etc, captured by existing
>>>>>>>> ExceptionMapper<WebApplicationException>  mappers if no a mapper
>>>>>>>> like
>>>>>>>> ExceptionMapper<NotFoundException>  exists, but a regression has
>>>>>>>> been
>>>>>>>> introduced.
>>>>>>>>
>>>>>>> It is the other way around, if we have
>>>>>>> ExceptionMapper<NotFoundException>  but the code has thrown "new
>>>>>>> WebApplicationException(404)" then NotFoundExceptionMapper should be
>>>>>>> chosen given that NotFoundException extends WebApplicationException.
>>>>>>>
>>>>>>> I can see that the exception is lost in all the cases where the
>>>>>>> origin
>>>>>>> ex is WebApplicationException and the mapper is not known to CXF,
>>>>>>> it is
>>>>>>> really to do with a wrong constructor check, still looking, but will
>>>>>>> likely fix early next week due to the long weekend coming in
>>>>>>>
>>>>>>> The tests show that if you register say
>>>>>>> ExceptionMapper<InternalServerErrorException>  and throw
>>>>>>> InternalServerErrorException then no cause exception is lost, in
>>>>>>> meantime I'll have a look at the other cases
>>>>>>>
>>>>>>> Cheers, Sergey
>>>>>>>
>>>>>>>> The possible workarounds: provide
>>>>>>>> ExceptionMapper<ServerErrorException>
>>>>>>>> or extend CXF WebApplicationExceptionMapper. Another one is CXF
>>>>>>>> specific
>>>>>>>> and it is to register a custom CXF invoker which will get a chance
>>>>>>>> to
>>>>>>>> capture the original WebApplicationException, I guess it should be
>>>>>>>> the
>>>>>>>> last resort option, I'll provide more info if doing other exception
>>>>>>>> mappers won't help
>>>>>>>>
>>>>>>>> Thanks, Sergey
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks
>>>>>>>>>
>>>>>>>>> Duncan
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>
>> --
>> Sergey Beryozkin
>>
>> Talend Community Coders
>> http://coders.talend.com/
>>
>> Blog: http://sberyozkin.blogspot.com
>


Re: CXF 2.7.0 loosing original exception message after wrapping in WebApplicationException

Posted by "Duncan Keysell (dkeysell)" <dk...@cisco.com>.
Hi Sergey,
Thanks everything is working fine with the latest 2.7.1-SNAPSHOT.

Thanks
Duncan

On 05/11/2012 10:39, "Sergey Beryozkin" <sb...@gmail.com> wrote:

>Hi,
>
>I've reverted to the original code, but also updated the RS code to
>throw WAE subclasses where possible as per the spec, example,
>NotFoundException will be thrown instead of
>WebApplicationException(404), etc
>
>Thanks, Sergey
>
>
>On 02/11/12 15:28, Sergey Beryozkin wrote:
>> Hi Duncan
>> On 02/11/12 12:13, Duncan Keysell (dkeysell) wrote:
>>> Hi Sergey,
>>>
>>> The temporary workaround is not working for me :-(. I am getting class
>>> cast exception. This is because in my application I also have an
>>> exception:
>>>
>>> public class XMPWebApplicationException extends
>>>WebApplicationException {
>>> Š.
>>> {
>>>
>>> And a mapper for it:
>>>
>>> public class XMPWebAppExceptionMapper implements
>>> ExceptionMapper<XMPWebApplicationException> {
>>> Š.
>>> }
>>>
>>> So with the workaround in JAXRSUtils.convertFaultToResponse(T ex,
>>>Message
>>> inMessage) that is provided in 2.7.1-SNAPSHOT:
>>>
>>> Again the mapper and the exception satisfy the if statement and so the
>>> exception get changed to a javax.ws.rs.BadRequestException inside
>>> getWebApplicationExceptionClass method but the mapper is still
>>>expecting
>>> to receive a XMPWebApplicationException or a subclass. So this causes
>>> class cast exception.
>>>
>>
>> I'm going to revert to the original code (the one that was there in
>> 2.6.x) asap. It appears I've misinterpreted what exactly we've agreed to
>> awhile back on the spec list re mapping WebApplicationExceptions on the
>> server side.
>>
>> While I still think that there's a certain degree of ambiguity with
>> application-thrown WebApplicationExceptions not being mapped to
>> specialized WebApplicationException subclass mappers, example
>> (WebApplicationException(404) -> NotFoundException mapper), I'm going to
>> drop this code and revert to the old one.
>>
>> Thanks for the patience
>> Sergey
>>
>>>
>>>
>>> Thanks
>>> Duncan
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On 30/10/2012 13:47, "Sergey Beryozkin"<sb...@gmail.com> wrote:
>>>
>>>> Hi Duncan
>>>>
>>>> On 30/10/12 11:16, Duncan Keysell (dkeysell) wrote:
>>>>> Hi,
>>>>>
>>>>> Thanks for the update. I'm building my application against
>>>>> 2.7.1-SNAPSHOT
>>>>> now so I can try out a fix once you've had a time to look at this
>>>>>:-).
>>>>
>>>> I've just committed a temporarily fix. I'm looking for the final
>>>> confirmation on whether this mapping of base WebApplicationExceptions
>>>>to
>>>> WebApplicationException subclass mappers will be actually supported,
>>>>if
>>>> yes - then I will optimize the current solution, if not - I will
>>>>revert
>>>> to the original code - I'll keep you up to date
>>>>
>>>> Thanks for reporting this issue,
>>>>
>>>> Sergey
>>>>
>>>>>
>>>>> Thanks
>>>>> Duncan
>>>>>
>>>>> On 25/10/2012 18:15, "Sergey Beryozkin"<sb...@gmail.com> wrote:
>>>>>
>>>>>> On 25/10/12 17:17, Sergey Beryozkin wrote:
>>>>>>> Hi Duncan
>>>>>>>
>>>>>>> Thanks for the analysis, comments inline
>>>>>>>
>>>>>>> On 25/10/12 14:18, Duncan Keysell (dkeysell) wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> In the application code for my REST service all the exceptions are
>>>>>>>> wrapped in WebApplicationException and then thrown. I have a test
>>>>>>>> case
>>>>>>>> to check this is working and below is the resource called in that
>>>>>>>> test
>>>>>>>> case:
>>>>>>>>
>>>>>>>>
>>>>>>>> @GET
>>>>>>>>
>>>>>>>> @Path("/plainBad")
>>>>>>>>
>>>>>>>> public MgmtResponse throwPlainException() throws Exception {
>>>>>>>>
>>>>>>>> throw new WebApplicationException(new Exception("Some lame
>>>>>>>> message"));
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> I have an exception mapper (implementation of
>>>>>>>> ExceptionMapper<WebApplicationException>) that creates the
>>>>>>>>Response.
>>>>>>>> This Response contains the message from the original exception as
>>>>>>>> well
>>>>>>>> as the exception type, up until I have moved to use 2.7.0.
>>>>>>>>
>>>>>>>>
>>>>>>>> This is due to a change in the
>>>>>>>>JAXRSUtils.convertFaultToResponse(T,
>>>>>>>> Message) message between 2.6.2 and 2.7.0.
>>>>>>>>
>>>>>>>>
>>>>>>>> Previously the method was (line 1217):
>>>>>>>>
>>>>>>>>
>>>>>>>> public static<T extends Throwable> Response
>>>>>>>>convertFaultToResponse(T
>>>>>>>> ex, Message inMessage) {
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> ExceptionMapper<T> mapper =
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> 
>>>>>>>>ProviderFactory.getInstance(inMessage).createExceptionMapper(ex.get
>>>>>>>>Cla
>>>>>>>>
>>>>>>>> ss
>>>>>>>> (),
>>>>>>>> inMessage);
>>>>>>>>
>>>>>>>> if (mapper != null) {
>>>>>>>>
>>>>>>>> try {
>>>>>>>>
>>>>>>>> return mapper.toResponse(ex);
>>>>>>>>
>>>>>>>> } catch (Exception mapperEx) {
>>>>>>>>
>>>>>>>> mapperEx.printStackTrace();
>>>>>>>>
>>>>>>>> return Response.serverError().build();
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> return null;
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> And now it is (line 1352):
>>>>>>>>
>>>>>>>>
>>>>>>>> @SuppressWarnings("unchecked")
>>>>>>>>
>>>>>>>> public static<T extends Throwable> Response
>>>>>>>>convertFaultToResponse(T
>>>>>>>> ex, Message inMessage) {
>>>>>>>>
>>>>>>>> ProviderFactory factory = ProviderFactory.getInstance(inMessage);
>>>>>>>>
>>>>>>>> ExceptionMapper<T> mapper = factory.createExceptionMapper(ex,
>>>>>>>> inMessage);
>>>>>>>>
>>>>>>>> if (mapper != null) {
>>>>>>>>
>>>>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>>>>
>>>>>>>> && mapper.getClass() != WebApplicationExceptionMapper.class) {
>>>>>>>>
>>>>>>>> WebApplicationException webEx = (WebApplicationException)ex;
>>>>>>>>
>>>>>>>> Class<?> exceptionClass =
>>>>>>>> getWebApplicationExceptionClass(webEx.getResponse(),
>>>>>>>>
>>>>>>>> WebApplicationException.class);
>>>>>>>>
>>>>>>>> if (exceptionClass != WebApplicationException.class) {
>>>>>>>>
>>>>>>>> try {
>>>>>>>>
>>>>>>>> Constructor<?> ctr =
>>>>>>>>exceptionClass.getConstructor(Response.class);
>>>>>>>>
>>>>>>>> ex = (T)ctr.newInstance(webEx.getResponse());
>>>>>>>>
>>>>>>>> } catch (Exception ex2) {
>>>>>>>>
>>>>>>>> ex2.printStackTrace();
>>>>>>>>
>>>>>>>> return Response.serverError().build();
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> try {
>>>>>>>>
>>>>>>>> return mapper.toResponse(ex);
>>>>>>>>
>>>>>>>> } catch (Exception mapperEx) {
>>>>>>>>
>>>>>>>> mapperEx.printStackTrace();
>>>>>>>>
>>>>>>>> return Response.serverError().build();
>>>>>>>>
>>>>>>>> } finally {
>>>>>>>>
>>>>>>>> factory.clearExceptionMapperProxies();
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> return null;
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> So the problem is that the exception 'ex' and my 'mapper' pass
>>>>>>>> the if
>>>>>>>> statement (line 1356):
>>>>>>>>
>>>>>>>>
>>>>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>>>>
>>>>>>>> && mapper.getClass() != WebApplicationExceptionMapper.class)
>>>>>>>>
>>>>>>>>
>>>>>>>> And then the ex gets over written and I loose all the details that
>>>>>>>> the
>>>>>>>> original WebApplicationException was holding. Shouldn't the if
>>>>>>>> statement be changed not to allow any mapping implementing
>>>>>>>> ExceptionMapper<WebApplicationException>? Is there some workaround
>>>>>>>> for
>>>>>>>> this?
>>>>>>>>
>>>>>>> I'm going to work on test case shortly. The actual change was
>>>>>>>needed
>>>>>>> to
>>>>>>> get new JAX-RS 2.0 exceptions such as NotFoundException
>>>>>>>(alternative
>>>>>>> to
>>>>>>> new WebApplicationException(404)), etc, captured by existing
>>>>>>> ExceptionMapper<WebApplicationException> mappers if no a mapper
>>>>>>>like
>>>>>>> ExceptionMapper<NotFoundException> exists, but a regression has
>>>>>>>been
>>>>>>> introduced.
>>>>>>>
>>>>>> It is the other way around, if we have
>>>>>> ExceptionMapper<NotFoundException> but the code has thrown "new
>>>>>> WebApplicationException(404)" then NotFoundExceptionMapper should be
>>>>>> chosen given that NotFoundException extends WebApplicationException.
>>>>>>
>>>>>> I can see that the exception is lost in all the cases where the
>>>>>>origin
>>>>>> ex is WebApplicationException and the mapper is not known to CXF,
>>>>>> it is
>>>>>> really to do with a wrong constructor check, still looking, but will
>>>>>> likely fix early next week due to the long weekend coming in
>>>>>>
>>>>>> The tests show that if you register say
>>>>>> ExceptionMapper<InternalServerErrorException> and throw
>>>>>> InternalServerErrorException then no cause exception is lost, in
>>>>>> meantime I'll have a look at the other cases
>>>>>>
>>>>>> Cheers, Sergey
>>>>>>
>>>>>>> The possible workarounds: provide
>>>>>>> ExceptionMapper<ServerErrorException>
>>>>>>> or extend CXF WebApplicationExceptionMapper. Another one is CXF
>>>>>>> specific
>>>>>>> and it is to register a custom CXF invoker which will get a chance
>>>>>>>to
>>>>>>> capture the original WebApplicationException, I guess it should be
>>>>>>> the
>>>>>>> last resort option, I'll provide more info if doing other exception
>>>>>>> mappers won't help
>>>>>>>
>>>>>>> Thanks, Sergey
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>>
>>>>>>>> Duncan
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>
>-- 
>Sergey Beryozkin
>
>Talend Community Coders
>http://coders.talend.com/
>
>Blog: http://sberyozkin.blogspot.com


Re: CXF 2.7.0 loosing original exception message after wrapping in WebApplicationException

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi,

I've reverted to the original code, but also updated the RS code to 
throw WAE subclasses where possible as per the spec, example, 
NotFoundException will be thrown instead of 
WebApplicationException(404), etc

Thanks, Sergey


On 02/11/12 15:28, Sergey Beryozkin wrote:
> Hi Duncan
> On 02/11/12 12:13, Duncan Keysell (dkeysell) wrote:
>> Hi Sergey,
>>
>> The temporary workaround is not working for me :-(. I am getting class
>> cast exception. This is because in my application I also have an
>> exception:
>>
>> public class XMPWebApplicationException extends WebApplicationException {
>> Š.
>> {
>>
>> And a mapper for it:
>>
>> public class XMPWebAppExceptionMapper implements
>> ExceptionMapper<XMPWebApplicationException> {
>> Š.
>> }
>>
>> So with the workaround in JAXRSUtils.convertFaultToResponse(T ex, Message
>> inMessage) that is provided in 2.7.1-SNAPSHOT:
>>
>> Again the mapper and the exception satisfy the if statement and so the
>> exception get changed to a javax.ws.rs.BadRequestException inside
>> getWebApplicationExceptionClass method but the mapper is still expecting
>> to receive a XMPWebApplicationException or a subclass. So this causes
>> class cast exception.
>>
>
> I'm going to revert to the original code (the one that was there in
> 2.6.x) asap. It appears I've misinterpreted what exactly we've agreed to
> awhile back on the spec list re mapping WebApplicationExceptions on the
> server side.
>
> While I still think that there's a certain degree of ambiguity with
> application-thrown WebApplicationExceptions not being mapped to
> specialized WebApplicationException subclass mappers, example
> (WebApplicationException(404) -> NotFoundException mapper), I'm going to
> drop this code and revert to the old one.
>
> Thanks for the patience
> Sergey
>
>>
>>
>> Thanks
>> Duncan
>>
>>
>>
>>
>>
>>
>>
>>
>> On 30/10/2012 13:47, "Sergey Beryozkin"<sb...@gmail.com> wrote:
>>
>>> Hi Duncan
>>>
>>> On 30/10/12 11:16, Duncan Keysell (dkeysell) wrote:
>>>> Hi,
>>>>
>>>> Thanks for the update. I'm building my application against
>>>> 2.7.1-SNAPSHOT
>>>> now so I can try out a fix once you've had a time to look at this :-).
>>>
>>> I've just committed a temporarily fix. I'm looking for the final
>>> confirmation on whether this mapping of base WebApplicationExceptions to
>>> WebApplicationException subclass mappers will be actually supported, if
>>> yes - then I will optimize the current solution, if not - I will revert
>>> to the original code - I'll keep you up to date
>>>
>>> Thanks for reporting this issue,
>>>
>>> Sergey
>>>
>>>>
>>>> Thanks
>>>> Duncan
>>>>
>>>> On 25/10/2012 18:15, "Sergey Beryozkin"<sb...@gmail.com> wrote:
>>>>
>>>>> On 25/10/12 17:17, Sergey Beryozkin wrote:
>>>>>> Hi Duncan
>>>>>>
>>>>>> Thanks for the analysis, comments inline
>>>>>>
>>>>>> On 25/10/12 14:18, Duncan Keysell (dkeysell) wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> In the application code for my REST service all the exceptions are
>>>>>>> wrapped in WebApplicationException and then thrown. I have a test
>>>>>>> case
>>>>>>> to check this is working and below is the resource called in that
>>>>>>> test
>>>>>>> case:
>>>>>>>
>>>>>>>
>>>>>>> @GET
>>>>>>>
>>>>>>> @Path("/plainBad")
>>>>>>>
>>>>>>> public MgmtResponse throwPlainException() throws Exception {
>>>>>>>
>>>>>>> throw new WebApplicationException(new Exception("Some lame
>>>>>>> message"));
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> I have an exception mapper (implementation of
>>>>>>> ExceptionMapper<WebApplicationException>) that creates the Response.
>>>>>>> This Response contains the message from the original exception as
>>>>>>> well
>>>>>>> as the exception type, up until I have moved to use 2.7.0.
>>>>>>>
>>>>>>>
>>>>>>> This is due to a change in the JAXRSUtils.convertFaultToResponse(T,
>>>>>>> Message) message between 2.6.2 and 2.7.0.
>>>>>>>
>>>>>>>
>>>>>>> Previously the method was (line 1217):
>>>>>>>
>>>>>>>
>>>>>>> public static<T extends Throwable> Response convertFaultToResponse(T
>>>>>>> ex, Message inMessage) {
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> ExceptionMapper<T> mapper =
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> ProviderFactory.getInstance(inMessage).createExceptionMapper(ex.getCla
>>>>>>>
>>>>>>> ss
>>>>>>> (),
>>>>>>> inMessage);
>>>>>>>
>>>>>>> if (mapper != null) {
>>>>>>>
>>>>>>> try {
>>>>>>>
>>>>>>> return mapper.toResponse(ex);
>>>>>>>
>>>>>>> } catch (Exception mapperEx) {
>>>>>>>
>>>>>>> mapperEx.printStackTrace();
>>>>>>>
>>>>>>> return Response.serverError().build();
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> return null;
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> And now it is (line 1352):
>>>>>>>
>>>>>>>
>>>>>>> @SuppressWarnings("unchecked")
>>>>>>>
>>>>>>> public static<T extends Throwable> Response convertFaultToResponse(T
>>>>>>> ex, Message inMessage) {
>>>>>>>
>>>>>>> ProviderFactory factory = ProviderFactory.getInstance(inMessage);
>>>>>>>
>>>>>>> ExceptionMapper<T> mapper = factory.createExceptionMapper(ex,
>>>>>>> inMessage);
>>>>>>>
>>>>>>> if (mapper != null) {
>>>>>>>
>>>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>>>
>>>>>>> && mapper.getClass() != WebApplicationExceptionMapper.class) {
>>>>>>>
>>>>>>> WebApplicationException webEx = (WebApplicationException)ex;
>>>>>>>
>>>>>>> Class<?> exceptionClass =
>>>>>>> getWebApplicationExceptionClass(webEx.getResponse(),
>>>>>>>
>>>>>>> WebApplicationException.class);
>>>>>>>
>>>>>>> if (exceptionClass != WebApplicationException.class) {
>>>>>>>
>>>>>>> try {
>>>>>>>
>>>>>>> Constructor<?> ctr = exceptionClass.getConstructor(Response.class);
>>>>>>>
>>>>>>> ex = (T)ctr.newInstance(webEx.getResponse());
>>>>>>>
>>>>>>> } catch (Exception ex2) {
>>>>>>>
>>>>>>> ex2.printStackTrace();
>>>>>>>
>>>>>>> return Response.serverError().build();
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> try {
>>>>>>>
>>>>>>> return mapper.toResponse(ex);
>>>>>>>
>>>>>>> } catch (Exception mapperEx) {
>>>>>>>
>>>>>>> mapperEx.printStackTrace();
>>>>>>>
>>>>>>> return Response.serverError().build();
>>>>>>>
>>>>>>> } finally {
>>>>>>>
>>>>>>> factory.clearExceptionMapperProxies();
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> return null;
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> So the problem is that the exception 'ex' and my 'mapper' pass
>>>>>>> the if
>>>>>>> statement (line 1356):
>>>>>>>
>>>>>>>
>>>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>>>
>>>>>>> && mapper.getClass() != WebApplicationExceptionMapper.class)
>>>>>>>
>>>>>>>
>>>>>>> And then the ex gets over written and I loose all the details that
>>>>>>> the
>>>>>>> original WebApplicationException was holding. Shouldn't the if
>>>>>>> statement be changed not to allow any mapping implementing
>>>>>>> ExceptionMapper<WebApplicationException>? Is there some workaround
>>>>>>> for
>>>>>>> this?
>>>>>>>
>>>>>> I'm going to work on test case shortly. The actual change was needed
>>>>>> to
>>>>>> get new JAX-RS 2.0 exceptions such as NotFoundException (alternative
>>>>>> to
>>>>>> new WebApplicationException(404)), etc, captured by existing
>>>>>> ExceptionMapper<WebApplicationException> mappers if no a mapper like
>>>>>> ExceptionMapper<NotFoundException> exists, but a regression has been
>>>>>> introduced.
>>>>>>
>>>>> It is the other way around, if we have
>>>>> ExceptionMapper<NotFoundException> but the code has thrown "new
>>>>> WebApplicationException(404)" then NotFoundExceptionMapper should be
>>>>> chosen given that NotFoundException extends WebApplicationException.
>>>>>
>>>>> I can see that the exception is lost in all the cases where the origin
>>>>> ex is WebApplicationException and the mapper is not known to CXF,
>>>>> it is
>>>>> really to do with a wrong constructor check, still looking, but will
>>>>> likely fix early next week due to the long weekend coming in
>>>>>
>>>>> The tests show that if you register say
>>>>> ExceptionMapper<InternalServerErrorException> and throw
>>>>> InternalServerErrorException then no cause exception is lost, in
>>>>> meantime I'll have a look at the other cases
>>>>>
>>>>> Cheers, Sergey
>>>>>
>>>>>> The possible workarounds: provide
>>>>>> ExceptionMapper<ServerErrorException>
>>>>>> or extend CXF WebApplicationExceptionMapper. Another one is CXF
>>>>>> specific
>>>>>> and it is to register a custom CXF invoker which will get a chance to
>>>>>> capture the original WebApplicationException, I guess it should be
>>>>>> the
>>>>>> last resort option, I'll provide more info if doing other exception
>>>>>> mappers won't help
>>>>>>
>>>>>> Thanks, Sergey
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Thanks
>>>>>>>
>>>>>>> Duncan
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>

-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: CXF 2.7.0 loosing original exception message after wrapping in WebApplicationException

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Duncan
On 02/11/12 12:13, Duncan Keysell (dkeysell) wrote:
> Hi Sergey,
>
> The temporary workaround is not working for me :-(. I am getting class
> cast exception. This is because in my application I also have an exception:
>
> public class XMPWebApplicationException extends WebApplicationException {
> Š.
> {
>
> And a mapper for it:
>
> public class XMPWebAppExceptionMapper implements
> ExceptionMapper<XMPWebApplicationException>  {
> Š.
> }
>
> So with the workaround in JAXRSUtils.convertFaultToResponse(T ex, Message
> inMessage) that is provided in 2.7.1-SNAPSHOT:
>
> Again the mapper and the exception satisfy the if statement and so the
> exception get changed to a javax.ws.rs.BadRequestException inside
> getWebApplicationExceptionClass method but the mapper is still expecting
> to receive a XMPWebApplicationException or a subclass. So this causes
> class cast exception.
>

I'm going to revert to the original code (the one that was there in 
2.6.x) asap. It appears I've misinterpreted what exactly we've agreed to 
awhile back on the spec list re mapping WebApplicationExceptions on the 
server side.

While I still think that there's a certain degree of ambiguity with 
application-thrown WebApplicationExceptions not being mapped to 
specialized WebApplicationException subclass mappers, example 
(WebApplicationException(404) -> NotFoundException mapper), I'm going to 
drop this code and revert to the old one.

Thanks for the patience
Sergey

>
>
> Thanks
> Duncan
>
>
>
>
>
>
>
>
> On 30/10/2012 13:47, "Sergey Beryozkin"<sb...@gmail.com>  wrote:
>
>> Hi Duncan
>>
>> On 30/10/12 11:16, Duncan Keysell (dkeysell) wrote:
>>> Hi,
>>>
>>> Thanks for the update. I'm building my application against
>>> 2.7.1-SNAPSHOT
>>> now so I can try out a fix once you've had a time to look at this :-).
>>
>> I've just committed a temporarily fix. I'm looking for the final
>> confirmation on whether this mapping of base WebApplicationExceptions to
>> WebApplicationException subclass mappers will be actually supported, if
>> yes - then I will optimize the current solution, if not - I will revert
>> to the original code - I'll keep you up to date
>>
>> Thanks for reporting this issue,
>>
>> Sergey
>>
>>>
>>> Thanks
>>> Duncan
>>>
>>> On 25/10/2012 18:15, "Sergey Beryozkin"<sb...@gmail.com>   wrote:
>>>
>>>> On 25/10/12 17:17, Sergey Beryozkin wrote:
>>>>> Hi Duncan
>>>>>
>>>>> Thanks for the analysis, comments inline
>>>>>
>>>>> On 25/10/12 14:18, Duncan Keysell (dkeysell) wrote:
>>>>>> Hi,
>>>>>>
>>>>>> In the application code for my REST service all the exceptions are
>>>>>> wrapped in WebApplicationException and then thrown. I have a test
>>>>>> case
>>>>>> to check this is working and below is the resource called in that
>>>>>> test
>>>>>> case:
>>>>>>
>>>>>>
>>>>>> @GET
>>>>>>
>>>>>> @Path("/plainBad")
>>>>>>
>>>>>> public MgmtResponse throwPlainException() throws Exception {
>>>>>>
>>>>>> throw new WebApplicationException(new Exception("Some lame
>>>>>> message"));
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> I have an exception mapper (implementation of
>>>>>> ExceptionMapper<WebApplicationException>) that creates the Response.
>>>>>> This Response contains the message from the original exception as
>>>>>> well
>>>>>> as the exception type, up until I have moved to use 2.7.0.
>>>>>>
>>>>>>
>>>>>> This is due to a change in the JAXRSUtils.convertFaultToResponse(T,
>>>>>> Message) message between 2.6.2 and 2.7.0.
>>>>>>
>>>>>>
>>>>>> Previously the method was (line 1217):
>>>>>>
>>>>>>
>>>>>> public static<T extends Throwable>   Response convertFaultToResponse(T
>>>>>> ex, Message inMessage) {
>>>>>>
>>>>>>
>>>>>>
>>>>>> ExceptionMapper<T>   mapper =
>>>>>>
>>>>>>
>>>>>>
>>>>>> ProviderFactory.getInstance(inMessage).createExceptionMapper(ex.getCla
>>>>>> ss
>>>>>> (),
>>>>>> inMessage);
>>>>>>
>>>>>> if (mapper != null) {
>>>>>>
>>>>>> try {
>>>>>>
>>>>>> return mapper.toResponse(ex);
>>>>>>
>>>>>> } catch (Exception mapperEx) {
>>>>>>
>>>>>> mapperEx.printStackTrace();
>>>>>>
>>>>>> return Response.serverError().build();
>>>>>>
>>>>>> }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>> return null;
>>>>>>
>>>>>>
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> And now it is (line 1352):
>>>>>>
>>>>>>
>>>>>> @SuppressWarnings("unchecked")
>>>>>>
>>>>>> public static<T extends Throwable>   Response convertFaultToResponse(T
>>>>>> ex, Message inMessage) {
>>>>>>
>>>>>> ProviderFactory factory = ProviderFactory.getInstance(inMessage);
>>>>>>
>>>>>> ExceptionMapper<T>   mapper = factory.createExceptionMapper(ex,
>>>>>> inMessage);
>>>>>>
>>>>>> if (mapper != null) {
>>>>>>
>>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>>
>>>>>> &&   mapper.getClass() != WebApplicationExceptionMapper.class) {
>>>>>>
>>>>>> WebApplicationException webEx = (WebApplicationException)ex;
>>>>>>
>>>>>> Class<?>   exceptionClass =
>>>>>> getWebApplicationExceptionClass(webEx.getResponse(),
>>>>>>
>>>>>> WebApplicationException.class);
>>>>>>
>>>>>> if (exceptionClass != WebApplicationException.class) {
>>>>>>
>>>>>> try {
>>>>>>
>>>>>> Constructor<?>   ctr = exceptionClass.getConstructor(Response.class);
>>>>>>
>>>>>> ex = (T)ctr.newInstance(webEx.getResponse());
>>>>>>
>>>>>> } catch (Exception ex2) {
>>>>>>
>>>>>> ex2.printStackTrace();
>>>>>>
>>>>>> return Response.serverError().build();
>>>>>>
>>>>>> }
>>>>>>
>>>>>> }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>> try {
>>>>>>
>>>>>> return mapper.toResponse(ex);
>>>>>>
>>>>>> } catch (Exception mapperEx) {
>>>>>>
>>>>>> mapperEx.printStackTrace();
>>>>>>
>>>>>> return Response.serverError().build();
>>>>>>
>>>>>> } finally {
>>>>>>
>>>>>> factory.clearExceptionMapperProxies();
>>>>>>
>>>>>> }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>> return null;
>>>>>>
>>>>>>
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>> So the problem is that the exception 'ex' and my 'mapper' pass the if
>>>>>> statement (line 1356):
>>>>>>
>>>>>>
>>>>>> if (ex.getClass() == WebApplicationException.class
>>>>>>
>>>>>> &&   mapper.getClass() != WebApplicationExceptionMapper.class)
>>>>>>
>>>>>>
>>>>>> And then the ex gets over written and I loose all the details that
>>>>>> the
>>>>>> original WebApplicationException was holding. Shouldn't the if
>>>>>> statement be changed not to allow any mapping implementing
>>>>>> ExceptionMapper<WebApplicationException>? Is there some workaround
>>>>>> for
>>>>>> this?
>>>>>>
>>>>> I'm going to work on test case shortly. The actual change was needed
>>>>> to
>>>>> get new JAX-RS 2.0 exceptions such as NotFoundException (alternative
>>>>> to
>>>>> new WebApplicationException(404)), etc, captured by existing
>>>>> ExceptionMapper<WebApplicationException>   mappers if no a mapper like
>>>>> ExceptionMapper<NotFoundException>   exists, but a regression has been
>>>>> introduced.
>>>>>
>>>> It is the other way around, if we have
>>>> ExceptionMapper<NotFoundException>   but the code has thrown "new
>>>> WebApplicationException(404)" then NotFoundExceptionMapper should be
>>>> chosen given that NotFoundException extends WebApplicationException.
>>>>
>>>> I can see that the exception is lost in all the cases where the origin
>>>> ex is WebApplicationException and the mapper is not known to CXF, it is
>>>> really to do with a wrong constructor check, still looking, but will
>>>> likely fix early next week due to the long weekend coming in
>>>>
>>>> The tests  show that if you register say
>>>> ExceptionMapper<InternalServerErrorException>   and throw
>>>> InternalServerErrorException then no cause exception is lost, in
>>>> meantime I'll have a look at the other cases
>>>>
>>>> Cheers, Sergey
>>>>
>>>>> The possible workarounds: provide
>>>>> ExceptionMapper<ServerErrorException>
>>>>> or extend CXF WebApplicationExceptionMapper. Another one is CXF
>>>>> specific
>>>>> and it is to register a custom CXF invoker which will get a chance to
>>>>> capture the original WebApplicationException, I guess it should be the
>>>>> last resort option, I'll provide more info if doing other exception
>>>>> mappers won't help
>>>>>
>>>>> Thanks, Sergey
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>> Duncan
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Sergey Beryozkin
>>>>
>>>> Talend Community Coders
>>>> http://coders.talend.com/
>>>>
>>>> Blog: http://sberyozkin.blogspot.com
>>>
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com