users@jersey.java.net

RE: [Jersey] Jersey Issues with JAXB classes without @XmlRootElement - XSD, XJC, Inheritance

From: James Allchin <james_at_knowledgemill.com>
Date: Mon, 5 Oct 2009 10:03:09 -0700

Ah OK - thanks Paul... interesting...

This will certainly help with the GETs. I will give it a go.

As you point out I will still be affected by GETs with List<T> based return types.

I suspect I will also be facing similar issues with POST, PUT, and DELETE where I wish to unmarshall the Artifact(s) directly from the XML/JSON payload of these methods.

Thanks,

James

-----Original Message-----
From: Paul Sandoz [mailto:Paul.Sandoz_at_Sun.COM]
Sent: Monday, October 05, 2009 10:00 AM
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] Jersey Issues with JAXB classes without @XmlRootElement - XSD, XJC, Inheritance

Hi James,

I am not sure that annotating Artifact with @XmlRootElement is the
right approach. Because, i presume, when you marshall you want to the
root element to be that of the concrete type.

I think Jersey is being too restrictive. Currently the type that is
utilized to analyze whether JAXB can be utilized is the return type of
the method. I suspect you are doing the following:

   @GET
   public Artifact get(...) {
     Artifact a = ... // create an instance of EmailArtifact
     return a;
   }

Correct?

Can you try the following workaround:

  @GET
  public Response get(...) {
     Artifact a = ... // create an instance of EmailArtifact
     return Response.ok(a).build();
  }

does the above work?

If so I need to fix things such that the return type of the method is
only used if:

   method.getReturnType() != method.getGenericReturnType()

i.e. we need to utilize the return type of the method say when
returning List<T>.

Paul.

On Oct 3, 2009, at 9:56 PM, James Allchin wrote:

> Hi,
>
> Although not directly related to Jersey - there is a side-effect
> problem caused to Jersey by XSD, XJC and class inheritance. I
> therefore, hope that someone has seen this before...
>
> Essentially, if you have complex types that extend other complex
> types within your XSD, then the resulting base classes do not have
> an @XmlRootElement annotation. This causes problems for Jersey it
> seems because natively we can do GETs PUTs etc against JAXB classes
> that have the @XmlType annotation only (without the @XmlRootElement).
>
> I do not want to resort to having to use JAXBElement type methods
> through an ObjectFactory (I have seen this on previous postings).
>
> Has anyone from the group experienced this and solved it (without
> manually adding back in the XmlRootElement annotation to the base
> classes)?
>
> For more information, I have also included the original question
> that I posed on StackOverflow below.
>
> Thanks for any help you can give.
>
> Regards,
>
> James
> ------------------------------
>
> I have a relatively simple XSD file defining my XML schema. The
> complex types within the XSD take advantage of inheritance using the
> tags. The problem I having is that I need all complex types to
> generate Java Classes with the @XmlRootElement.
>
> Unfortunately, the way in which XJC generates the classes means that
> only derived class gets the @XmlRootElement (not the base class). I
> am using the simple global binding directive to ensure that it
> solves many of the other issues that I have faced with XJC.
>
> Here is an example snippet of the XSD:
>
> <xs:element name="Artifact" type="kmcs:Artifact"/>
> <xs:element name="EmailArtifact" type="kmcs:EmailArtifact"/>
>
> <xs:complexType name="Artifact">
> <xs:sequence>
> <xs:element name="artifactId" type="xs:string" minOccurs="0"/>
> <xs:element name="artifactType" type="xs:string"
> minOccurs="0"/>
> <xs:element name="contentHash" type="xs:string" minOccurs="0"/>
> </xs:sequence>
> </xs:complexType>
>
> <xs:complexType name="EmailArtifact">
> <xs:complexContent>
> <xs:extension base="kmcs:Artifact">
> <xs:sequence>
> <xs:element name="subject" type="xs:string"
> minOccurs="0"/>
> <xs:element name="threadSubject" type="xs:string"
> minOccurs="0"/>
> <xs:element name="from" type="xs:string"
> minOccurs="0"/>
> <xs:element name="to" type="xs:string" minOccurs="0"/>
> <xs:element name="cc" type="xs:string" minOccurs="0"/>
> <xs:element name="bcc" type="xs:string" minOccurs="0"/>
> <xs:element name="messageId" type="xs:string"
> minOccurs="0"/>
> <xs:element name="date" type="xs:date" minOccurs="0"/>
> <xs:element name="size" type="xs:long" minOccurs="0"/>
> <xs:element name="hasAttachment" type="xs:boolean"
> minOccurs="0"/>
> <xs:element name="sensitivity" type="xs:string"
> minOccurs="0"/>
> <xs:element name="headerHash" type="xs:string"
> minOccurs="0"/>
> </xs:sequence>
> </xs:extension>
> </xs:complexContent>
> </xs:complexType>
>
> As we can see from the above snippet, EmailArtifact extends Artifact.
>
> The java class code for EmailArtifact contains the following:
>
> @XmlAccessorType(XmlAccessType.FIELD)
> @XmlType(name = "EmailArtifact", propOrder = {
> "subject",
> "threadSubject",
> "from",
> "to",
> "cc",
> "bcc",
> "messageId",
> "date",
> "size",
> "hasAttachment",
> "sensitivity",
> "headerHash"
> })
> @XmlSeeAlso({
> ExtendedEmail.class
> })
> @XmlRootElement(name = "EmailArtifact")
> public class EmailArtifact
> extends Artifact
> {
>
> protected String subject;
> protected String threadSubject;
> protected String from;
> protected String to;
> protected String cc;
> protected String bcc;
> protected String messageId;
> @XmlSchemaType(name = "date")
> protected XMLGregorianCalendar date;
> protected Long size;
> protected Boolean hasAttachment;
> protected String sensitivity;
> protected String headerHash;
>
> The java class code for Artifact contains the following:
>
> @XmlAccessorType(XmlAccessType.FIELD)
> @XmlType(name = "Artifact", propOrder = {
> "artifactId",
> "artifactType",
> "contentHash"
> })
> @XmlSeeAlso({
> ManagedDocArtifact.class,
> EmailArtifact.class
> })
> public class Artifact {
>
> protected String artifactId;
> protected String artifactType;
> protected String contentHash;
>
> In the EmailArtifact we can see that it contains the @XmlRootElement
> but the base type Artifact does not contain @XmlRootElement.
>
> How can you force XJC to generate @XmlRootElement for all classes
> including the base types.
>
> Thanks,
>
> James
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>