axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Iltchenko, Andrei" <Andrei.Iltche...@nl.compuware.com>
Subject Question on the changes to 'SymbolTable.faultsFromSOAPFault'
Date Mon, 25 Aug 2003 11:22:27 GMT
Hello all,

We've been wrestling with a problem when deserializing exceptions on the
client side. The problem is caused by the way QNames for FaultInfo objects
are formed. The following pieces of code taken from AXIS 1.1 release clarify
the issue.


SymbolTable.faultsFromSOAPFault:
		...
		...
            String soapFaultNamespace = "";
            
            Iterator faultIter =
bFault.getExtensibilityElements().iterator();
            for (; faultIter.hasNext();) {
                Object obj = faultIter.next();
                if (obj instanceof SOAPFault) {
                    foundSOAPFault = true;
                    soapFaultUse = ((SOAPFault)obj).getUse();
                    soapFaultNamespace = ((SOAPFault)obj).getNamespaceURI();
                    break;
                } else if (obj instanceof UnknownExtensibilityElement) {
			...
			...                
                }
            }

            // Check to make sure we have a soap:fault element
            if (!foundSOAPFault) {
                ...
            }

            // TODO error checking:
            // if use=literal, no use of namespace on the soap:fault
            // if use=encoded, no use of element on the part

            // Check this fault to make sure it matches the one
            // in the matching portType Operation
            Fault opFault = operation.getFault(bFault.getName());
            if (opFault == null) {
                ...
            }
            // put the updated entry back in the map
            faults.add(new FaultInfo(opFault,
                    Use.getUse(soapFaultUse),
                    soapFaultNamespace,
                    this));



FaultDesc:
    ...
    ...
    public FaultDesc(QName qname, String className,
                     QName xmlType, boolean complex) {
        this.qname = qname;
        this.className = className;
        this.xmlType = xmlType;
        this.complex = complex;
    }

    public QName getQName() {
        return qname;
    }
    ...
    ...


As a result of these changes, the QName of a FaultDescr object is a
combination of the name of the fault's message part and the value of the
fault's namespace attribute, e.g. the QName of a FaultInfo object generated
for the following soap fault element would be '{urn:AddressFetcher2}ex'.

  <wsdl:message name="Exception">
    <wsdl:part name="ex" type="typens:addressException"/>
  </wsdl:message>

  <wsdl:binding name="name" type="typens:AddressBook">
    ...
    <wsdl:operation name="addEntry">
      ...
      <wsdl:fault name="fa">
        <soap:fault name="SoapFault" use="encoded"
namespace="urn:AddressFetcher2"/>
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>


This poses problems when deserializing faults with code generated by
WSDL2Java for documents similar to the one below:

  <wsdl:message name="Exception">
    <wsdl:part name="ex" type="typens:addressException"/>
  </wsdl:message>
  <wsdl:message name="Exception1">
    <wsdl:part name="ex" type="typens1:addressException1"/>
  </wsdl:message>


  <wsdl:binding name="name" type="typens:AddressBook">
    ...
    <wsdl:operation name="addEntry">
	...
      <wsdl:fault name="fa">
        <soap:fault name="SoapFault" use="encoded"
namespace="urn:AddressFetcher2"/>
      </wsdl:fault>
      <wsdl:fault name="fa1">
        <soap:fault name="SoapFault1" use="encoded"
namespace="urn:AddressFetcher2"/>
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>

Here we will have to FaultInfo objects whose QName's are identical, and the
following piece of code from 'SOAPFaultDetailsBuilder.onStartChild' will
always find the first FaultInfo object registered for the operation called:

        MessageContext msgContext = context.getMessageContext();
        SOAPConstants soapConstants = msgContext.getSOAPConstants();
        OperationDesc op = msgContext.getOperation();
        Class faultClass = null;
        QName faultXmlType = null;
        if (op != null) {
            FaultDesc faultDesc = op.getFaultByQName(qn);  // <-- finds the
first descr.
            // allow fault type to be denoted in xsi:type
            if (faultDesc == null) {
                ...
            } else {
                faultXmlType = faultDesc.getXmlType();    
            }
            if (faultDesc != null) {
                // Set the class
                try {
                    faultClass =
ClassUtils.forName(faultDesc.getClassName());
                } catch (ClassNotFoundException e) {
                    // Just create an AxisFault, no custom exception
                }
            }
        } else {
            ...          
        }

As a result, on the client side, an exception object of type
'typens:addressException' will be constructed, even though an exception of
type 'typens1:addressException1' might have been thrown on the server.


We have two questions:
1. What piece of the WSDL 1.1 specification gives the lattitude to identify
soap faults in this manner?
2. If not, is this a known bug which is planned to be fixed?

We tracked this behaviour down to the changes of dims as of 2003/01/19.


Thank you in advance,
Andrei.


-- 
The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it. 


Mime
View raw message