Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-1052

CXF throws ClassCastException from generated client code [when multiple elements have the same name in WSDL]

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Blocker
    • Resolution: Fixed
    • 2.0.1
    • 2.0.2
    • JAX-WS Runtime
    • None
    • Windows XP, Java 1.5

    Description

      I'm getting ClassCastExceptions from within a dynamically created proxy when using CXF as a client against a webservice. The WSDL for the service is attached, but some parts are shown here:

      <message name='InvoiceDS_getInvoiceData'>
      <part element='tns:getInvoiceData' name='parameters'/> </message> <message name='InvoiceDS_getInvoiceDataResponse'>
      <part element='tns:getInvoiceDataResponse' name='result'/> </message> <portType name='InvoiceDS'>
      <operation name='getInvoiceData'>
      <input message='tns:InvoiceDS_getInvoiceData'/>
      <output message='tns:InvoiceDS_getInvoiceDataResponse'/>
      <fault message='tns:WebServiceFault' name='WebService'/>
      </operation>
      </portType>

      All classes are genereated with WSDL2Java, the resulting interface for the service being (removed annotations for readability):

      public interface InvoiceDS {
      public java.util.List<localhost.jaws.InvoiceData> getInvoiceData(
      localhost.jaws.InvoiceRequest invoiceRequest
      ) throws WebServiceFault_Exception;
      }

      The InvoiceDS interface specifies that a List of InvoiceData objects should be returned from the method. This means that the GetInvoiceDataResponse type is not used and CXF must unwrap the result from the response before returning it to the client.

      My testcode looks something like this:
      {
      QName SERVICE = new QName("http://localhost/jaws", "InvoiceServiceDS");
      InvoiceServiceDS service = new InvoiceServiceDS(new URL("InvoiceWs.wsdl"), SERVICE);
      InvoiceDS client =service.getInvoiceDSPort();
      InvoiceRequest invoiceRequest = new InvoiceRequest();
      invoiceRequest.setCustId("test123");

      List<InvoiceData> invoiceData =
      client.getInvoiceData(invoiceRequest);
      }

      Digging into the CXF framework with the debugger we end up in the
      JaxWsClientProxy.invoke() method, line 191 has the return statement:
      191 return result;

      result is of type GetInvoiceDataResponse (as specified in the WSDL) and not the list that was expected.

      After looking into this issue more closely I discovered that the problem arises from the fact that 2 elements in the WSDL have the same name and this makes CXF generate the wrong client code.

      Snippet of original WSDL file:

      <complexType name='InvoiceData'>
      <sequence>
      <element name='custID' nillable='true' type='string'/>
      </sequence>
      </complexType>
      <complexType name='InvoiceRequest'>
      <sequence>
      <element name='custId' nillable='true' type='string'/>
      </sequence>
      </complexType>
      <complexType name='getInvoiceData'>
      <sequence>
      <element name='InvoiceRequest' nillable='true'
      type='tns:InvoiceRequest'/>
      </sequence>
      </complexType>
      <complexType name='getInvoiceDataResponse'>
      <sequence>
      <element maxOccurs='unbounded' minOccurs='0' name='result'
      nillable='true' type='tns:InvoiceData'/>
      </sequence>
      </complexType>
      <element name='getInvoiceData' type='tns:getInvoiceData'/>
      <element name='getInvoiceDataResponse'
      type='tns:getInvoiceDataResponse'/>
      </schema>
      </types>
      <message name='InvoiceDS_getInvoiceData'>
      <part element='tns:getInvoiceData' name='parameters'/> </message> <message name='InvoiceDS_getInvoiceDataResponse'>
      <part element='tns:getInvoiceDataResponse' name='result'/> </message> <portType name='InvoiceDS'>
      <operation name='getInvoiceData'>
      <input message='tns:InvoiceDS_getInvoiceData'/>
      <output message='tns:InvoiceDS_getInvoiceDataResponse'/>
      </operation>
      </portType>

      ------
      In the new version I've changed the operation name to "getInvoiceDataOperation" and thus CXF will render a working client for me.

      WSDL snippet:
      <complexType name='InvoiceData'>
      <sequence>
      <element name='custID'
      nillable='true'
      type='string' />
      </sequence>
      </complexType>
      <complexType name='InvoiceRequest'>
      <sequence>
      <element name='custId'
      nillable='true'
      type='string' />
      </sequence>
      </complexType>
      <complexType name='getInvoiceData'>
      <sequence>
      <element name='InvoiceRequest'
      nillable='true'

      type='tns:InvoiceRequest' />
      </sequence>
      </complexType>
      <complexType name='getInvoiceDataResponse'>
      <sequence>
      <element maxOccurs='unbounded'
      minOccurs='0'
      name='result'
      nillable='true' type='tns:InvoiceData' />
      </sequence>
      </complexType>
      <element name='getInvoiceData'
      type='tns:getInvoiceData' />
      <element name='getInvoiceDataResponse'
      type='tns:getInvoiceDataResponse' />
      </schema>
      </types>
      <message name='InvoiceDS_getInvoiceData'>
      <part element='tns:getInvoiceData' name='parameters' />
      </message>
      <message name='InvoiceDS_getInvoiceDataResponse'>
      <part element='tns:getInvoiceDataResponse' name='result'
      />
      </message>
      <portType name='InvoiceDS'>
      <operation name='getInvoiceDataOperation'>
      <input message='tns:InvoiceDS_getInvoiceData' />
      <output
      message='tns:InvoiceDS_getInvoiceDataResponse' />
      </operation>
      </portType>

      public localhost.jaws.GetInvoiceDataResponse getInvoiceDataOperation(
      @WebParam(targetNamespace = "http://localhost/jaws", partName = "parameters", name = "getInvoiceData")
      localhost.jaws.GetInvoiceData parameters
      );

      Seems to be a problem when there are multiple elements with the same name (a datatype and a message) but I'm assuming that should be ok according to the specs - since the WSDL works with other SOAP stacks (.Net, Axis2, JBoss-WS)?

      Attachments

        1. InvoiceWs.wsdl
          3 kB
          Peter Liljenberg

        Issue Links

          Activity

            People

              Unassigned Unassigned
              pliljenberg@gmail.com Peter Liljenberg
              Votes:
              7 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: