Axis2: Avoid "Unexpected subelement" error when non-required property added to WSDL
Asked Answered
I

1

2

I have a .NET WCF service and a Java app that uses Axis2 to generate service stubs. When I add an optional property to a data contract in WCF and sort it at the end of the property list (which should be a backwards-compatible change) it causes Unexpected subelement errors in the Java app. The only way to fix it is to regenerate the stubs in Axis2 and redeploy the Java app -- not an acceptable approach in my case.

To be clear, I have not changed the order of the properties and the WSDL is valid. Here's an example of a type from the WSDL from before (when the Java app worked) and after (which causes the "Unexpected subelement" error):

<!-- BEFORE -->
<xs:complexType name="MyObject">
   <xs:sequence>
      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/>
   </xs:sequence>
</xs:complexType>

<!-- AFTER -->
<xs:complexType name="MyObject">
   <xs:sequence>
      <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/>
      <xs:element minOccurs="0" name="MyNewProperty" nillable="true" type="xs:string"/>
   </xs:sequence>
</xs:complexType>

The AFTER version causes this error: org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected subelement {http://mycompany.com/services/}MyNewProperty

Is there something we can do with Axis2 to prevent this from happening? If not, is there something different we should do in the WSDL or on the WCF side?

Imparisyllabic answered 8/7, 2013 at 17:14 Comment(0)
P
3

It appears that this is not a backwards-compatible change from the point of view of the XML Schema. If I ask XSV to validate a message

<MyObject>
    <Name>Primus Secundus</Name>
    <MyNewProperty>Addita notitia</MyNewProperty>
</MyObject> 

against your <!-- BEFORE --> schema, I get an error indicating that the MyNewProperty is invalid:

Invalid per cvc-complex-type.1.2.4: element {None}:MyNewProperty not allowed here (2) in element {None}:MyObject, expecting [$]:

I can't find anything in the XML Schema documentation (http://www.w3.org/TR/xmlschema-1/) or in either SOAP version (http://www.w3.org/TR/soap/) which indicates that extending a sequence with new elements for new properties should be allowed.


I used XSV at http://www.w3.org/2001/03/webdata/xsv, and uploaded the data in the following wrapper:

<?xml version="1.0"?>
<wrapper xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="#mySchema">
    <xs:schema id="mySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="wrapper">
            <xs:complexType>
                <xs:sequence>
                    <xs:any/>
                    <xs:element name="MyObject" type="MyObject"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
        <!-- BEFORE -->
        <xs:complexType name="MyObject">
            <xs:sequence>
                <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:schema>
    <MyObject>
        <Name>Primus Secundus</Name>
        <MyNewProperty>Addita notitia</MyNewProperty>
    </MyObject> 
</wrapper>
Promiscuous answered 9/7, 2013 at 18:24 Comment(4)
Using JAXB for databinding in Axis may accept this even though it's not valid with respect to the schema, similar to how WCF clients seem to accept these changes as non-breaking.Promiscuous
Thanks. This debunks my assumption that my changes were backwards-compatible. However I'm still in need of a solution.Imparisyllabic
I'm still looking for one. We've been using WCF this way for years, but now we have one customer using Axis so when we add properties to return types it is a breaking change. I think we are going to either: go up a major version to hand written WSDLs that leave room for extension via something like <xs:choice minOccurs="0" maxOccurs="unbounded"><xs:any namespace="##other" processContents="strict"/><xs:any namespace="##local" processContents="strict"/></xs:choice>, possibly with "lax" or "skip" a la msdn.microsoft.com/en-us/library/aa468563.aspx or: add an endpoint for every change.Promiscuous
@Promiscuous Hey, I'm curious if you've found a good solution to this? We also have clients using Axis2 to whom adding a new property is a breaking change. Thanks!Rep

© 2022 - 2024 — McMap. All rights reserved.