Anne Thomas Manes wrote:

> There are two problems with this fault message:
> 1- The <SOAP-ENV:Fault> element must be the first and only child element in
> the <SOAP-ENV:Body> element. It cannot be a child of the <ns1:SomeFunction>
> element. If you want to return the <ns1:SomeFunction> information in the
> fault, it must be encoded within the <detail> element.
> 2- Content in the <detail> message must be namespace qualified.

I'm having a similar problem with Faults in Axis 1.2RC1. My service interface defines a method that throws an application-specific exception:

    public boolean doit(int id)
        throws RemoteException, InvalidIdException;
    ...
    public class InvalidIdException extends Exception {
        public InvalidIdException(int id, String msg) {
            super(msg);
            this.id = id;
        }
        public String getMessage() { return super.getMessage(); }
        public int getId() { return id; }
        private int id;
    }

I generated WSDL with Java2WSDL (style="wrapped" and use="literal") and deployed the service, then generated stubs with WSDL2Java and ran a client. When the service throws an InvalidIdException, the response Body looks like this (note that Axis does not add a namespace qualifier to the detail children):

<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>org.example.InvalidIdException</faultstring>
<detail>
<org.example.InvalidIdException>
<message>invalid id</message>
<id>-1</id>
</org.example.InvalidIdException>
<ns1:hostname xmlns:ns1="http://xml.apache.org/axis/";>EINSTEIN</ns1:hostname>
</detail>
</soapenv:Fault>
</soapenv:Body>


Oddly, the exception class generated by WSDL2Java defines a method named getMessage1 and a field named message1; there's no getMessage method override. A client using the generated stubs fails with a SAXException and the message "invalid element - message".

However, if I change the method name in InvalidIdException from getMessage to getMsg and assign the argument to a new field, the client runs without errors.

If I omit the getMessage method completely from my exception class, there's no <message> element defined in the generated WSDL. I thought that adding "--all" to Java2WSDL would force it to generate an element corresponding to Exception.getMessage, but "--all" doesn't seem to have any affect.

It seems that the presense of the <message> element in the fault definition confuses WSDL2Java. Is this an Axis bug or is there some configuration setting that will induce WSDL2Java to handle the <message> element correctly?

Mike



Anne Thomas Manes wrote:

There are two problems with this fault message:
1- The <SOAP-ENV:Fault> element must be the first and only child element in
the <SOAP-ENV:Body> element. It cannot be a child of the <ns1:SomeFunction>
element. If you want to return the <ns1:SomeFunction> information in the
fault, it must be encoded within the <detail> element.
2- Content in the <detail> message must be namespace qualified.


-Anne

-----Original Message-----
From: Trevor Porter [mailto:[EMAIL PROTECTED] Sent: Thursday, October 14, 2004 5:07 PM
To: [EMAIL PROTECTED]
Subject: SAXException trying to deserialize this fault


I'm trying to figure out why Axis throws a SAXException trying to deserialize the following SOAP message containing a fault:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"; SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"; xmlns:xsd="http://www.w3.org/1999/XMLSchema";>
<SOAP-ENV:Body>
<ns1:SomeFunction xmlns:ns1="urn:foo">
<Param1 xsi:type="xsd:string">some value</Param1>
<Param2 xsi:type="xsd:string">some value</Param2>
<SOAP-ENV:Fault>
<faultcode xsi:type="xsd:string">Client</faultcode>
<faultstring xsi:type="xsd:string">Client request/data invalid</faultstring>
<detail>
<message xsi:type="xsd:string">some message</message>
<errorcode xsi:type="xsd:string">-5</errorcode>
</detail>
</SOAP-ENV:Fault>
</ns1:SomeFunction>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


The code I'm using:

Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(endpoint);
call.setSOAPActionURI("SomeAction"); call.setOperationName(new QName("urn:foo", "SomeFunction"));
call.addParameter("Param1", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
call.addParameter("Param2", org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING);
String result = (String)call.invoke( new Object[] { "value1", "value2" } );


The exception stack trace that results:

org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
at org.apache.axis.encoding.ser.SimpleDeserializer.onStartChild(SimpleDeseriali
zer.java:149)
at org.apache.axis.encoding.DeserializationContext.startElement(Deserialization
Context.java:1025)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:159)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:
1138)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:308)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:342)
at org.apache.axis.client.Call.invoke(Call.java:2420)
at org.apache.axis.client.Call.invoke(Call.java:2319)
at org.apache.axis.client.Call.invoke(Call.java:1776)
remote exception=org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.





--

Mike Woinoski                      Pine Needle Consulting
mailto:[EMAIL PROTECTED]

Reply via email to