JAXB Missing XmlRootElement Exception

We recently transitioned some Web services from using XMLBeans to JAXB.  One odd thing that we noticed was that you couldn’t return a JAXB Type that followed this format defined in the XML Schema:

<element name="EchoResponse" type="tns:EchoResponseType"></element>

<complexType name="EchoResponseType">
    <sequence>
        <element name="input" type="string"></element>
    </sequence>
</complexType>

It would throw a missing an @XmlRootElement annotation exception.

There’s two ways of getting around this.  One way is to define an annotation inside the schema itself.  I don’t really recommend this because it makes your elements the Java objects rather than the more useful types, but it is an option.  Note you also have to use the -extension parameter for the xjc compiler.

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.qualcomm.com/pds/common/schema"
 targetNamespace="http://www.qualcomm.com/pds/common/schema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
 jaxb:version="1.0" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
 jaxb:extensionBindingPrefixes="xjc" elementFormDefault="qualified" attributeFormDefault="unqualified">
   <annotation>
     <appinfo>
        <jaxb:globalBindings>
           <xjc:simple />
        </jaxb:globalBindings>
     </appinfo>
 </annotation>

Another approach is to simply to do this code-side on the return type leaving the XMLSchema intact as follows:

marshaller.marshal(new JAXBElement(new QName("http://www.qualcomm.com/pds/common/schema",
 "EchoResponse"), EchoResponseType.class, response),
 System.out);

This way when the marshaller marshalls the XML it will be able to determine the parent element for the type that you are returning.