Found the answer, or the reason, so thought I would share.
The @XmlRootElement
annotation is useful for plain JAXB
bindings, but when the objects (and the resulting XML) are packaged as a SOAP
response it is possible that they don't exactly match the WSDL
's representation of the data depending on the value of other annotations.
With the @XmlRootElement
annotation on the class on the server which is being returned by a @WebMethod
method, the WSDL
will include an element definition such as:
<xs:element name="foo" type="tns:FooType"/>
then elsewhere your WSDL
will include a reference to the element in a sequence such as:
<xs:seqeunce>
<xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:foo"/>
</xs:sequence>
This referencing is caused by the @XmlRootElement
annotation may confuse the intent of the root element declaration compared to the actual XML of the SOAP response.
In contrast, the WSDL
generated without the @XmlRootElement
annotation on the server objects does not contain a <xs:element name="foo"/>
declaration at all. Rather its element is described as:
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="foo" type="tns:FooType"/>
</xs:sequence>
This probably better matches the way the SOAP response XML is represented and the unmarshalling of the XML into the classes generated by wsimport
works just fine.
How to use @XmlRootElement
in a JAX-WS
service?
wsimport
seems to handle some degree of laziness in the validity of the XML returned by a service. The lesson learned is to be diligent in your use of name
and targetNamespace
on your @WebResult
annotations describing your web service method. The @XmlRootElement
annotation needs to match the name
within the targetNamespace
. When they all match, the unmarshalling happens as expected. When those values do not match, your stubbed classes generated and annotated by wsimport
will not be able to properly consume the XML.