Reasons For Unexpected Subelement Exception In Axis2 Data Binding(ADB)
by Milinda Lakmal
WSDL2Java which comes with Apache Axis2 is tool that most of us use to generate web service clients and services giving WSDL as an input. If you have ever used WSDL2Java in your own projects you must came across this kind of exception at least once. Until you come up with a perfect WSDL and service implementation, you’ll have to fix this kind of errors.
Solving these type of issues is a pain, because it’s related to code generation and there may be hundreds of generated Java classes. I have came across this error several times due to issues of XML schemas and service implementation errors(implementation is not compliance with the XML schema). So here are some reasons for unexpected subelement exceptions. This will help you to minimize your debug time.
- You have XML schema ‘any’ in between sequence like following.When the code is generated using WSDL2Java ProcessInfoType’s inner Factory class’s parse method will generate code that process XML schema ‘any’ after the ‘version’ element. When parse method ‘any’ processing is over the XML reader is at the end of the sequence, so instead of ‘status’ element it’ll find ‘ProcessInfo’ element. So it’s better to double check whther you have XML schema ‘any’ element in between elements of a sequence. The correct way is to put ‘any’ at the last.
<xsd:complexType name="ProcessInfoType">
<xsd:annotation>
<xsd:documentation>Information about a BPEL Process. </xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="pid" type="xsd:string"/>
<xsd:element name="version" type="xsd:long"/>
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="status" type="tns:ProcessStatus"> </xsd:element>
<xsd:element name="definitionInfo" type="tns:DefinitionInfo"> </xsd:element>
<xsd:element name="deploymentInfo" type="tns:DeploymentInfo"> </xsd:element>
<xsd:element name="instanceSummary" type="tns:InstanceSummary" minOccurs="0"></xsd:element>
<xsd:element name="properties" type="tns:ProcessProperties"></xsd:element>
<xsd:element name="endpoints" type="tns:EndpointReferences"></xsd:element>
<xsd:element name="documents">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="document" type="tns:DocumentInfo" minOccurs="0"
maxOccurs="unbounded"> </xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:anyAttribute namespace="##other" processContents="lax"/ >
</xsd:complexType> - If we have complex type with sequence and the last element of the sequence don’t have minOccurs attribute. So the generated code expect that element while parsing the XML. But in the implementation we think that element’s minimum occurrences are zero. So if we have array of elements with the above complex type at the client side, it’ll failed to parse the response because of the missing minOccurs=”0″ attribute in XML schema. You can easily detec this kind of errors by comparing XML with the XML schema definition. Also elements with minOccurs 1 in between sequence of elements and in the implementation it has min occurs 0, will also caused unexpected sub element exception.
- If response or request XML must have a, b, c elements in a sequence and actual XML has a, d, c elements in the sequence, then Axis2 would complain saying that it received an Unexpected element named d.
- In RPC style WSDLs you can specify a WSDL message like following
<message name="testOutput">
<part name="scope-info" type="xns:tVariableInfo"/>
</message>But the implementation returns element called ‘variable-info’ which wraps the tVariableInfo type. Situation like this where we specify wrong WSDL message part names can also cause this error when using WSDL2Java ADB.
If you encounter above kind of situations while developing components for WSO2 Carbon platform, the best way to monitor the SOAP messages is using SOAP Tracer comes with most of the Carbon based products. This will help you to compare what implementation returns and what XML schema defines. If you are using Axis2 you can use TCP Monitor to monitor your SOAP communication between client and server.
There may be more reasons for this exception, so please feel free to share your experience with me.