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/10/06 09:35:09 UTC

Problem with resource that returns Object with CXF version >= 2.6.1

Hi,

I've inherited maintenance of a REST service that has a resource with the following interface:


@GET

    @Path("/{etype}")

    @Description("Return a list of all the instances of {etype}")

    Object findEntities(@PathParam("etype") String entityType, @Context MessageContext mx);


If I upgrade the service to use a recent version of CXF then it fails with the following message:


"No message body writer has been found for response class Object."


The service works with CXF versions 2.4.7, 2.5.0 and 2.6.0.


It fails with the message, above, with versions after and including 2.4.8 and 2.6.1. Not sure at which version in 2.5.x stream it stops working, but it does.


To check its not something I broke in my application code I took the jax_rs_basic project from the samples within the 2.6.0 and 2.6.1 distributions and changed the getCustomer method to return Object:


@GET

@Path("/customers/{id}/")

public Customer getCustomer(@PathParam("id") String id)


To


@GET

@Path("/customers/{id}/")

public Object getCustomer(@PathParam("id") String id)




I built this and found that it continues to work in 2.6.0 but fails in 2.6.1 with the "No message body writer has been found for response class Object."


Is this an intentional change in CXF or should I raise a bug for this?


Did I miss some configuration to handle this case? Do I need to start updating all my interfaces to return classes that are directly annotated with jaxb?



Thanks

Duncan




Re: Problem with resource that returns Object with CXF version >= 2.6.1

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

On 09/10/12 22:06, Sergey Beryozkin wrote:
> Hi Duncan
> On 09/10/12 12:22, Duncan Keysell (dkeysell) wrote:
>> Hi Sergey,
>>
>> Thanks for quick response. I am very interested to hear the outcome of
>> your investigation. For most of the methods I can indeed move away from
>> returning Object. However, we have a "framework" behind a few of the
>> resources that invokes methods that have registered with it and I really
>> don't know the class of object they will return as there is no
>> restriction
>> on what has been allowed, hence the Object.
>>
>> We have quite a larger number of implementations that are using this
>> "framework" so it will be difficult for me to change this behaviour. So,
>> hope you can support Object being returned as before.
>>
> I'd like to confirm this change in CXF is causing the issues with
> migrating to the newer CXF versions for cases where only Object is
> returned. I'll get back to you soon re the fix and the possible workaround.

The issue has been fixed - though I have to admit I think JAX-RS 
MessageBodyWriter (MBR) requiring passing an instance class makes it 
difficult to deal with the case where a payload has to contain "xsi:type".

Note MBR has both 'Class' and 'Object' parameters passed to it in its 
writeTo(...) method so they could've captured a type returned from 
Method and an instance class (object.getClass()) while now both this 
Class and object.getClass() is the same entity - but it is tricky to fix 
custom MBR expectations now due to backward compatibility concerns.

Either way, hope the next CXF release (2.5.x/2.6.x/2.7.x) will work just 
fine with only 'Object' being returned.

Finally a possible workaround if you'd like to start experimenting with 
already available newer CXF releases: customize JAXBElementProvider (I 
assuming it is JAXB that is used) to 'skipJaxbChecks' (set it to true - 
it also will lead to a slightly faster processing) and override 
JAXBElementProvider.writeTo by replacing a second (Class) parameter with 
object.getClass()...

thanks, Sergey

>
> Cheers, Sergey
>
>> Thanks
>> Duncan
>>
>> On 07/10/2012 17:56, "Sergey Beryozkin"<sb...@gmail.com> wrote:
>>
>>> Hi Duncan
>>> On 06/10/12 08:35, Duncan Keysell (dkeysell) wrote:
>>>> Hi,
>>>>
>>>> I've inherited maintenance of a REST service that has a resource with
>>>> the following interface:
>>>>
>>>>
>>>> @GET
>>>>
>>>> @Path("/{etype}")
>>>>
>>>> @Description("Return a list of all the instances of {etype}")
>>>>
>>>> Object findEntities(@PathParam("etype") String entityType,
>>>> @Context MessageContext mx);
>>>>
>>>>
>>>> If I upgrade the service to use a recent version of CXF then it fails
>>>> with the following message:
>>>>
>>>>
>>>> "No message body writer has been found for response class Object."
>>>>
>>>>
>>>> The service works with CXF versions 2.4.7, 2.5.0 and 2.6.0.
>>>>
>>>>
>>>> It fails with the message, above, with versions after and including
>>>> 2.4.8 and 2.6.1. Not sure at which version in 2.5.x stream it stops
>>>> working, but it does.
>>>>
>>>>
>>>> To check its not something I broke in my application code I took the
>>>> jax_rs_basic project from the samples within the 2.6.0 and 2.6.1
>>>> distributions and changed the getCustomer method to return Object:
>>>>
>>>>
>>>> @GET
>>>>
>>>> @Path("/customers/{id}/")
>>>>
>>>> public Customer getCustomer(@PathParam("id") String id)
>>>>
>>>>
>>>> To
>>>>
>>>>
>>>> @GET
>>>>
>>>> @Path("/customers/{id}/")
>>>>
>>>> public Object getCustomer(@PathParam("id") String id)
>>>>
>>>>
>>>>
>>>>
>>>> I built this and found that it continues to work in 2.6.0 but fails in
>>>> 2.6.1 with the "No message body writer has been found for response
>>>> class
>>>> Object."
>>>>
>>>>
>>>> Is this an intentional change in CXF or should I raise a bug for this?
>>>>
>>>>
>>>> Did I miss some configuration to handle this case? Do I need to start
>>>> updating all my interfaces to return classes that are directly
>>>> annotated
>>>> with jaxb?
>>>>
>>>>
>>>
>>> Thanks for the doing all the analysis above. The reason returning
>>> 'Object' stopped working is that now a class parameter that is passed
>>> to providers is determined exactly according to the method signature.
>>>
>>> For example, say 'Customer' is returned where Customer is interface.
>>> Originally providers would be passed 'CustomerImpl.class' instead of
>>> Customer.class but this was causing a number of issues to do with
>>> attaching the configuration to all Customer classes at the provider
>>> level, example for supporting the proper marshalling of subclasses,
>>> etc...
>>>
>>> I wonder though, given the example above, whether the change was
>>> entirely correct or not. I'll need to investigate more.
>>> Ideally, one would not return 'Object' but something more specific,
>>> example, abstract class/interface - this would also work well at the
>>> client (proxy) and WADL auto generation levels.
>>>
>>> So, if possible try to move away from returning Object. In meantime I'll
>>> investigate the issue more. If it happens that the update was not
>>> correct then I'll introduce a contextual property for users to be able
>>> to tell the runtime what to do - with the original (earlier) approach
>>> done by default
>>>
>>> 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

Re: Problem with resource that returns Object with CXF version >= 2.6.1

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Duncan
On 09/10/12 12:22, Duncan Keysell (dkeysell) wrote:
> Hi Sergey,
>
> Thanks for quick response. I am very interested to hear the outcome of
> your investigation. For most of the methods I can indeed move away from
> returning Object. However, we have a "framework" behind a few of the
> resources that invokes methods that have registered with it and I really
> don't know the class of object they will return as there is no restriction
> on what has been allowed, hence the Object.
>
> We have quite a larger number of implementations that are using this
> "framework" so it will be difficult for me to change this behaviour. So,
> hope you can support Object being returned as before.
>
I'd like to confirm this change in CXF is causing the issues with 
migrating to the newer CXF versions for cases where only Object is 
returned. I'll get back to you soon re the fix and the possible workaround.

Cheers, Sergey

> Thanks
> Duncan
>
> On 07/10/2012 17:56, "Sergey Beryozkin"<sb...@gmail.com>  wrote:
>
>> Hi Duncan
>> On 06/10/12 08:35, Duncan Keysell (dkeysell) wrote:
>>> Hi,
>>>
>>> I've inherited maintenance of a REST service that has a resource with
>>> the following interface:
>>>
>>>
>>> @GET
>>>
>>>       @Path("/{etype}")
>>>
>>>       @Description("Return a list of all the instances of {etype}")
>>>
>>>       Object findEntities(@PathParam("etype") String entityType,
>>> @Context MessageContext mx);
>>>
>>>
>>> If I upgrade the service to use a recent version of CXF then it fails
>>> with the following message:
>>>
>>>
>>> "No message body writer has been found for response class Object."
>>>
>>>
>>> The service works with CXF versions 2.4.7, 2.5.0 and 2.6.0.
>>>
>>>
>>> It fails with the message, above, with versions after and including
>>> 2.4.8 and 2.6.1. Not sure at which version in 2.5.x stream it stops
>>> working, but it does.
>>>
>>>
>>> To check its not something I broke in my application code I took the
>>> jax_rs_basic project from the samples within the 2.6.0 and 2.6.1
>>> distributions and changed the getCustomer method to return Object:
>>>
>>>
>>> @GET
>>>
>>> @Path("/customers/{id}/")
>>>
>>> public Customer getCustomer(@PathParam("id") String id)
>>>
>>>
>>> To
>>>
>>>
>>> @GET
>>>
>>> @Path("/customers/{id}/")
>>>
>>> public Object getCustomer(@PathParam("id") String id)
>>>
>>>
>>>
>>>
>>> I built this and found that it continues to work in 2.6.0 but fails in
>>> 2.6.1 with the "No message body writer has been found for response class
>>> Object."
>>>
>>>
>>> Is this an intentional change in CXF or should I raise a bug for this?
>>>
>>>
>>> Did I miss some configuration to handle this case? Do I need to start
>>> updating all my interfaces to return classes that are directly annotated
>>> with jaxb?
>>>
>>>
>>
>> Thanks for the doing all the analysis above. The reason returning
>> 'Object' stopped working is that now  a class parameter that is passed
>> to providers is determined exactly according to the method signature.
>>
>> For example, say 'Customer' is returned where Customer is interface.
>> Originally providers would be passed 'CustomerImpl.class' instead of
>> Customer.class but this was causing a number of issues to do with
>> attaching the configuration to all Customer classes at the provider
>> level, example for supporting the proper marshalling of subclasses, etc...
>>
>> I wonder though, given the example above, whether the change was
>> entirely correct or not. I'll need to investigate more.
>> Ideally, one would not return 'Object' but something more specific,
>> example, abstract class/interface - this would also work well at the
>> client (proxy) and WADL auto generation levels.
>>
>> So, if possible try to move away from returning Object. In meantime I'll
>> investigate the issue more. If it happens that the update was not
>> correct then I'll introduce a contextual property for users to be able
>> to tell the runtime what to do - with the original (earlier) approach
>> done by default
>>
>> Sergey
>>
>>
>>>
>>> Thanks
>>>
>>> Duncan
>>>
>>>
>>>
>>>
>>
>>
>> --
>> Sergey Beryozkin
>>
>> Talend Community Coders
>> http://coders.talend.com/
>>
>> Blog: http://sberyozkin.blogspot.com
>



Re: Problem with resource that returns Object with CXF version >= 2.6.1

Posted by "Duncan Keysell (dkeysell)" <dk...@cisco.com>.
Hi Sergey,

Thanks for quick response. I am very interested to hear the outcome of
your investigation. For most of the methods I can indeed move away from
returning Object. However, we have a "framework" behind a few of the
resources that invokes methods that have registered with it and I really
don't know the class of object they will return as there is no restriction
on what has been allowed, hence the Object.

We have quite a larger number of implementations that are using this
"framework" so it will be difficult for me to change this behaviour. So,
hope you can support Object being returned as before.

Thanks
Duncan

On 07/10/2012 17:56, "Sergey Beryozkin" <sb...@gmail.com> wrote:

>Hi Duncan
>On 06/10/12 08:35, Duncan Keysell (dkeysell) wrote:
>> Hi,
>>
>> I've inherited maintenance of a REST service that has a resource with
>>the following interface:
>>
>>
>> @GET
>>
>>      @Path("/{etype}")
>>
>>      @Description("Return a list of all the instances of {etype}")
>>
>>      Object findEntities(@PathParam("etype") String entityType,
>>@Context MessageContext mx);
>>
>>
>> If I upgrade the service to use a recent version of CXF then it fails
>>with the following message:
>>
>>
>> "No message body writer has been found for response class Object."
>>
>>
>> The service works with CXF versions 2.4.7, 2.5.0 and 2.6.0.
>>
>>
>> It fails with the message, above, with versions after and including
>>2.4.8 and 2.6.1. Not sure at which version in 2.5.x stream it stops
>>working, but it does.
>>
>>
>> To check its not something I broke in my application code I took the
>>jax_rs_basic project from the samples within the 2.6.0 and 2.6.1
>>distributions and changed the getCustomer method to return Object:
>>
>>
>> @GET
>>
>> @Path("/customers/{id}/")
>>
>> public Customer getCustomer(@PathParam("id") String id)
>>
>>
>> To
>>
>>
>> @GET
>>
>> @Path("/customers/{id}/")
>>
>> public Object getCustomer(@PathParam("id") String id)
>>
>>
>>
>>
>> I built this and found that it continues to work in 2.6.0 but fails in
>>2.6.1 with the "No message body writer has been found for response class
>>Object."
>>
>>
>> Is this an intentional change in CXF or should I raise a bug for this?
>>
>>
>> Did I miss some configuration to handle this case? Do I need to start
>>updating all my interfaces to return classes that are directly annotated
>>with jaxb?
>>
>>
>
>Thanks for the doing all the analysis above. The reason returning
>'Object' stopped working is that now  a class parameter that is passed
>to providers is determined exactly according to the method signature.
>
>For example, say 'Customer' is returned where Customer is interface.
>Originally providers would be passed 'CustomerImpl.class' instead of
>Customer.class but this was causing a number of issues to do with
>attaching the configuration to all Customer classes at the provider
>level, example for supporting the proper marshalling of subclasses, etc...
>
>I wonder though, given the example above, whether the change was
>entirely correct or not. I'll need to investigate more.
>Ideally, one would not return 'Object' but something more specific,
>example, abstract class/interface - this would also work well at the
>client (proxy) and WADL auto generation levels.
>
>So, if possible try to move away from returning Object. In meantime I'll
>investigate the issue more. If it happens that the update was not
>correct then I'll introduce a contextual property for users to be able
>to tell the runtime what to do - with the original (earlier) approach
>done by default
>
>Sergey
>
>
>>
>> Thanks
>>
>> Duncan
>>
>>
>>
>>
>
>
>-- 
>Sergey Beryozkin
>
>Talend Community Coders
>http://coders.talend.com/
>
>Blog: http://sberyozkin.blogspot.com


Re: Problem with resource that returns Object with CXF version >= 2.6.1

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Duncan
On 06/10/12 08:35, Duncan Keysell (dkeysell) wrote:
> Hi,
>
> I've inherited maintenance of a REST service that has a resource with the following interface:
>
>
> @GET
>
>      @Path("/{etype}")
>
>      @Description("Return a list of all the instances of {etype}")
>
>      Object findEntities(@PathParam("etype") String entityType, @Context MessageContext mx);
>
>
> If I upgrade the service to use a recent version of CXF then it fails with the following message:
>
>
> "No message body writer has been found for response class Object."
>
>
> The service works with CXF versions 2.4.7, 2.5.0 and 2.6.0.
>
>
> It fails with the message, above, with versions after and including 2.4.8 and 2.6.1. Not sure at which version in 2.5.x stream it stops working, but it does.
>
>
> To check its not something I broke in my application code I took the jax_rs_basic project from the samples within the 2.6.0 and 2.6.1 distributions and changed the getCustomer method to return Object:
>
>
> @GET
>
> @Path("/customers/{id}/")
>
> public Customer getCustomer(@PathParam("id") String id)
>
>
> To
>
>
> @GET
>
> @Path("/customers/{id}/")
>
> public Object getCustomer(@PathParam("id") String id)
>
>
>
>
> I built this and found that it continues to work in 2.6.0 but fails in 2.6.1 with the "No message body writer has been found for response class Object."
>
>
> Is this an intentional change in CXF or should I raise a bug for this?
>
>
> Did I miss some configuration to handle this case? Do I need to start updating all my interfaces to return classes that are directly annotated with jaxb?
>
>

Thanks for the doing all the analysis above. The reason returning 
'Object' stopped working is that now  a class parameter that is passed 
to providers is determined exactly according to the method signature.

For example, say 'Customer' is returned where Customer is interface. 
Originally providers would be passed 'CustomerImpl.class' instead of 
Customer.class but this was causing a number of issues to do with 
attaching the configuration to all Customer classes at the provider 
level, example for supporting the proper marshalling of subclasses, etc...

I wonder though, given the example above, whether the change was 
entirely correct or not. I'll need to investigate more.
Ideally, one would not return 'Object' but something more specific, 
example, abstract class/interface - this would also work well at the 
client (proxy) and WADL auto generation levels.

So, if possible try to move away from returning Object. In meantime I'll 
investigate the issue more. If it happens that the update was not 
correct then I'll introduce a contextual property for users to be able 
to tell the runtime what to do - with the original (earlier) approach 
done by default

Sergey


>
> Thanks
>
> Duncan
>
>
>
>


-- 
Sergey Beryozkin

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

Blog: http://sberyozkin.blogspot.com