cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: Problem with resource that returns Object with CXF version >= 2.6.1
Date Wed, 10 Oct 2012 12:22:28 GMT
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"<sberyozkin@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

Mime
View raw message