tags:

views:

2159

answers:

3

I am having some issues with generating Java Classes with appropriate JAXB annotations from an XSD using XJC.

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:schema version="1.0" targetNamespace="http://www.knowledgemill.com/kmcs"
  xmlns:kmcs="http://www.knowledgemill.com/kmcs"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
  jaxb:version="2.0"
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  jaxb:extensionBindingPrefixes="xjc"
  elementFormDefault="qualified">
    <xs:annotation>
        <xs:appinfo>
            <jaxb:globalBindings>
                <xjc:simple />
            </jaxb:globalBindings>
        </xs:appinfo>
    </xs:annotation>

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


</xs:schema>

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.

A: 

There are some clues here. Might have something to do with the reference to a type, as opposed to an internally specified type on an element. If you don't have control over the schemas it probably won't help you.

http://markmail.org/message/whw2dnphwp2grrlp

Ross Judson
A: 

Good answer is here http://javathought.wordpress.com/2009/04/25/xml-binding-with-jaxb-13/

Mariusz
Actually, no answer is there, and only comments complaining about the crappy post. :)
benvolioT
+1  A: 

This question references a blog post by Kohsuke Kawaguchi, formerly worked on the JAX-B or JAX-WS RI, that talks about the RI's decision making process and lack of clarity on this issue in the spec.

The blog post mentions that the simple binding feature is part of the RI. Are you using the RI to generate your code?

DavidValeri