Integration always hides some surprises especially when it comes to old systems where quick solutions aren’t the first aid. In this post, we present a strange and rare situation when requesting WS using an old existing WSDL. To make things simple bellow the wsdl and xsd samples :

OldExistingWsService.wsdl

<!--?xml version="1.0" encoding="UTF-8"?-->
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://ws.jtunisie.com/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetnamespace="http://ws.jtunisie.com/" name="OldExistingWsService">
   <types>
      <xsd:schema>
         <xsd:import namespace="http://ws.jtunisie.com/" schemalocation="./OldExistingWsService.xsd" />
      </xsd:schema>
   </types>
   <message name="oldOperation">
      <part name="parameters" element="tns:oldOperation" />
   </message>
   <message name="oldOperationResponse">
      <part name="parameters" element="tns:oldOperationResponse" />
   </message>
   <porttype name="OldExistingWs">
      <operation name="oldOperation">
         <input wsam:action="http://ws.jtunisie.com/OldExistingWs/oldOperationRequest" message="tns:oldOperation" />
         <output wsam:action="http://ws.jtunisie.com/OldExistingWs/oldOperationResponse" message="tns:oldOperationResponse" />
      </operation>
   </porttype>
   <binding name="OldExistingWsPortBinding" type="tns:OldExistingWs">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document">
         <operation name="oldOperation">
            <soap:operation soapaction="">
               <input>
                  <soap:body use="literal" />
               </input>
               <output>
                  <soap:body use="literal" />
               </output>
            </soap:operation>
         </operation>
      </soap:binding>
   </binding>
   <service name="OldExistingWsService">
      <port name="OldExistingWsPort" binding="tns:OldExistingWsPortBinding">
         <soap:address location="http://ouertani:8080/Wsdlcustomisation/OldExistingWsService" />
      </port>
   </service>
</definitions>

OldExistingWsService.xsd

<!--?xml version="1.0" encoding="UTF-8"?-->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.jtunisie.com/" version="1.0" targetnamespace="http://ws.jtunisie.com/">
   <xs:element name="oldOperation" type="tns:oldOperation">
      <xs:element name="oldOperationResponse" type="tns:oldOperationResponse">
         <xs:complextype name="oldOperation">
            <xs:sequence>
               <xs:element name="parameter" type="tns:oldExsistingClass" minoccurs="0" />
            </xs:sequence>
         </xs:complextype>
         <xs:complextype name="oldExsistingClass">
            <xs:sequence>
               <xs:element name="a" type="xs:int" />
               <xs:element name="_a" type="xs:int" />
            </xs:sequence>
         </xs:complextype>
         <xs:complextype name="oldOperationResponse">
            <xs:sequence>
               <xs:element name="return" type="xs:int" />
            </xs:sequence>
         </xs:complextype>
      </xs:element>
   </xs:element>
</xs:schema>

trying to generate java client code from this wsdl will causes : (wsdl2java.sh -client -d . -verbose OldExistingWsService.wsdl)

org.apache.cxf.tools.common.ToolException: Thrown by JAXB: Two declarations cause a collision in the ObjectFactory class. at line 17 column 1 of schema file:/OldExistingWsService.xsd

The problem is where a and _a are generate the same property, getter and setter methods names which generate exception.

    By quick solution, I means :
  1. tell cxf to resolve name collision with : -autoNameResolution command line argument
  2. tell jaxb to not remove underscores with : jaxb:globalBindings underscoreBinding="asCharInWord"

As these tricks doesn’t work for the current case, hands on dirty jaxb binding customization :

<jxb:bindings version="2.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <jxb:bindings schemalocation="file:OldExistingWsService.xsd" node="/xs:schema">
 	<jxb:bindings node=".//xs:element[@name='_a']">
     <jxb:property name="oldA"></jxb:property>
    </jxb:bindings>
 </jxb:bindings>
</jxb:bindings>

And tell : wsdl2java.sh -client -d . -verbose -b binding.xsd OldExistingWsService.wsdl

Note : to deal with old wsdl I used this schema bindings :

<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings xmlns:jaxws="http://java.sun.com/xm l/ns/jaxws" xmlns="http://java.sun.com/xml/ns/jaxws" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:tns1="VOLARISWS" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" wsdllocation="test.wsdl">
   <jaxws:schemabindings>
      <jaxws:bindings node="wsdl:definitions">
         <jaxws:bindings node=".//xs:element[@name='_a']">
            <jxb:property name="oldA" />
         </jaxws:bindings>
      </jaxws:bindings>
   </jaxws:schemabindings>
</jaxws:bindings>

Thanks for patience.