(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 >
