(Sorry Sergey for the dup message, I forgot to reply to all last time...)

It seems that I get all sorts of weird issues with EMF+JAXB.

For example, if I have a base class of Customer and two inherited
classes of GoodCustomer and BadCustomer. Then I have a WebStore as a
container for a list of Customer objects. The mind-twisting (for me at
least) problem is that if Customer is not defined as abstract in the
ecore model, I cannot even create the JAXBContext for WebStore (well,
actually WebStoreImpl for EMF), with a NoSuchElementException. If I
change Customer to be abstract, then at least it works in this aspect.

I tried plain java classes (hand-written, without interface/impl,
without proxy), it works no matter Customer is abstract or not...

-Simon

On Mon, Apr 18, 2011 at 11:02 AM, Sergey Beryozkin <[email protected]> wrote:
> Sorry for the noise, I think I've got totally confused - no @XmlSeeAlso has
> to be added to subclasses. But, I have a test where
>
> SuperBook extends Book, Book has @XmlSeeAlso pointing to SuperBook, and
> without using JAXBElement (internally), xsi:type is not written when Book is
> returned, however, no extra classes or jaxb.index is used, so that might
> explain why...
>
> Cheers, Sergey
>
>
>
> On Mon, Apr 18, 2011 at 3:57 PM, Sergey Beryozkin <[email protected]>
> wrote:
>>
>> That should work with adapters too, with @XmlSeeAlso.
>>
>> Actually, I remember now what adding a jaxbElementClassNames property
>> (containing a CustomerImpl full class name only in this particular case) can
>> do, it may help with avoiding adding @XmlSeeAlso to subclasses, I see a test
>> where only a base class has @XmlSeeAlso - somehow JAXBElement figures it out
>> that xsi:type has to be added...
>> Adding jaxb.index  extra classes for JAXBContext to include them should
>> also help...
>>
>> thanks, Sergey
>>
>> On Mon, Apr 18, 2011 at 3:36 PM, Daniel Kulp <[email protected]> wrote:
>>>
>>> When dealing with polymorphism with JAXB, one thing that is often
>>> required is
>>> to add XmlSeeAlso annotations all over the place.  In particular, on the
>>> base
>>> class, it's  useful to have XmlSeeAlso point at the potential subclasses.
>>> This allows the jaxb runtime to find the subclasses to instantiate and
>>> will
>>> usually result in the proper xsi:type attributes written out and such.
>>>
>>> If you haven't already tried it, I'd definitely suggest adding the
>>> annotation
>>> and seeing if that helps.
>>>
>>> Dan
>>>
>>>
>>> On Friday 15 April 2011 4:02:17 PM Simon Chen wrote:
>>> > Hi all,
>>> >
>>> > I've been playing with building a REST web service to handle
>>> > polymorphism... It's a long post, but bear with me :-)
>>> >
>>> > In particular, I may have:
>>> >
>>> > @Path("/")
>>> > class WebStore {
>>> >   @POST
>>> >   @Path("/customers/")
>>> >   Response addCustomer(Customer c) {
>>> >     ...
>>> >   }
>>> > }
>>> >
>>> > But I have a base class of Customer, but also inherited classes of
>>> > AwesomeCustomer, and SuperAwesomeCustomer. Things get more complicated
>>> > when EMF kicks in, where I actually have a Customer interface and
>>> > CustomerImpl class.
>>> >
>>> > The previous declaration doesn't work when I post a customer XML
>>> > snippet,
>>> > say: <customer><name>simon</name></customer>
>>> >
>>> > Because Customer is an interface, so cannot be annotated with
>>> > @XmlRootElement. As a result, the error of "no message body reader can
>>> > be found" is raised...
>>> >
>>> > If we change the POST function this way, it can work:
>>> >   @POST
>>> >   @Path("/customers/")
>>> >   Response addCustomer(CustomerImpl c) {
>>> >     ...
>>> >   }
>>> >
>>> > But, this breaks again, when I add the following:
>>> >   @POST
>>> >   @Path("/customers/")
>>> >   Response addCustomer(CustomerImpl c) {
>>> >     ...
>>> >   }
>>> >   @POST
>>> >   @Path("/customers/")
>>> >   Response addCustomer(AwesomeCustomerImpl c) {
>>> >     ...
>>> >   }
>>> >   @POST
>>> >   @Path("/customers/")
>>> >   Response addCustomer(SuperAwesomeCustomerImpl c) {
>>> >     ...
>>> >   }
>>> >
>>> > Here, if I post a SuperAwesomeCustomerImpl object to "/customers", the
>>> > ws would find all the functions that can handle "POST to /customers",
>>> > which will include all three functions above. However, in
>>> >
>>> > "src/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.
>>> > java", public static OperationResourceInfo findTargetMethod(), we have:
>>> >
>>> >         if (!candidateList.isEmpty()) {
>>> >             Map.Entry<OperationResourceInfo, MultivaluedMap<String,
>>> > String>> firstEntry =
>>> >                 candidateList.entrySet().iterator().next();
>>> >             //---------> This only looks at the first function that
>>> > matches, while not look at the class hierarchy...
>>> >             values.clear();
>>> >             values.putAll(firstEntry.getValue());
>>> >             OperationResourceInfo ori = firstEntry.getKey();
>>> >
>>> >
>>> > Hopefully, I am not overwhelming everyone with too much information.
>>> > But is there a fix to this problem? I guess maybe add some class
>>> > hierarchy-awareness to findTargetMethod()?
>>> >
>>> > Thanks!
>>> > -Simon
>>>
>>> --
>>> Daniel Kulp
>>> [email protected]
>>> http://dankulp.com/blog
>>> Talend - http://www.talend.com
>>
>>
>> Application Integration Division of Talend
>> http://sberyozkin.blogspot.com
>
>
>
> --
> Sergey Beryozkin
>
> Application Integration Division of Talend
> http://sberyozkin.blogspot.com
>

Reply via email to