You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by David Green <da...@maketechnologies.com> on 2003/04/30 20:42:48 UTC

RE: exception and SOAP fault

The following patch to AxisFault ensures that any exception that has a serializer registered will serialize the exception details
to the SOAP fault without having to have the exception class extend AxisFault:

Index: java/src/org/apache/axis/AxisFault.java
===================================================================
RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/AxisFault.java,v
retrieving revision 1.74
diff -r1.74 AxisFault.java
756c756,768
<         // no data in default Axis fault
---
>       Object detailObject = (getCause()==null)?this:getCause();
>       boolean haveSerializer = false;
>       try {
>         if (context.getTypeMapping().getSerializer(getClass())!=null) {
>           haveSerializer = true;
>         }
>       } catch (Exception e) {
>         // swallow this exception, it means that we don't know how to serialize
>         // the details.
>       }
>       if (haveSerializer) {        
>         context.serialize(qname, null, detailObject);
>       }

I apologize for the cross-post.  It's not clear to me which list should be used for contributions.

David

-----Original Message-----
From: David Green 
Sent: Wednesday, April 30, 2003 11:00 AM
To: axis-user@ws.apache.org
Subject: RE: exception and SOAP fault


Thomas,

Thankyou -- it works.  From what I can tell, all that is needed for faults with data to work with any exception (not just exceptions that extend AxisFault) is for the following method to be implemented in AxisFault:


    /**
     *  Writes any exception data to the faultDetails
     * This is for overriding; it is empty in the base AxisFault
     */
    public void writeDetails(QName qname, SerializationContext context) throws java.io.IOException {
        // no data in default Axis fault
    }

As you can see, the current implementation does nothing.  It seems that the only reason we get the fault data with the WSDL2Java generated exception is due to the generated code overriding this method as follows:

    /**
     * Writes the exception data to the faultDetails
     */
    public void writeDetails(javax.xml.namespace.QName qname, org.apache.axis.encoding.SerializationContext context) throws 	java.io.IOException {
        context.serialize(qname, null, this);
    }

Perhaps it's too simplistic, but it seems that a reasonable modification to AxisFault would solve the problem.  All that would be needed is the following:

1. AxisFault.initFromException() would save the instance of the exception in a member variable.
2. AxisFault.writeDetails() would be implemented as follows:


    /**
     *  Writes any exception data to the faultDetails
     * This is for overriding; it is empty in the base AxisFault
     */
    public void writeDetails(QName qname, SerializationContext context) throws java.io.IOException {
      if (exceptionDetail != null) { // <----- this is the exception that was saved in initFromException()
        context.serialize(qname, null, exceptionDetail);
      }
    }

In any case, it's possible that I've missed something.  Is there some reason why this wasn't done already?  In any case, I'm going to try it here to see if there are any other side effects of doing this.

David


-----Original Message-----
From: David Green 
Sent: Wednesday, April 30, 2003 9:43 AM
To: axis-user@ws.apache.org
Subject: RE: exception and SOAP fault


Thomas,

Thankyou very much for your help.  I'll give it a try and let you know how it goes.

It's a shame that we must use axis-specific code in our exceptions on the server to make it work.

David

-----Original Message-----
From: Thomas.Rothfuss @ .de []
Sent: Tuesday, April 29, 2003 9:48 PM
To: axis-user@ws.apache.org
Subject: Re: exception and SOAP fault



Hi David,

I started with the WSDL file and created the java classes by using
WSDL2Java.

The exception class itself is derived from AxisFault:
    public class WoodCommanderException  extends org.apache.axis.AxisFault
implements java.io.Serializable

The method throwing the exception is declared like this:
    public Homag.WoodCommander.Soap.Value getValue(java.lang.String in0)
throws java.rmi.RemoteException,
Homag.WoodCommander.Soap.WoodCommanderException

In your case the BusinessException extends the TestException. Perhaps this
may be a problem in Axis. I never tried that.

I already posted my scenario in this mailing list. Here is the pointer:
    http://marc.theaimsgroup.com/?l=axis-user&m=104988960618062&w=2

Hope this will help

Thomas



|---------+---------------------------------->
|         |           "David Green"          |
|         |           <david.green@maketechno|
|         |           logies.com>            |
|         |                                  |
|         |                                  |
|         |                                  |
|         |           30.04.03 03:01         |
|         |           Bitte antworten an     |
|         |           axis-user              |
|         |                                  |
|---------+---------------------------------->
  >------------------------------------------------------------------------------------------------------------------------------|
  |                                                                                                                              |
  |       An:       <ax...@xml.apache.org>                                                                                   |
  |       Kopie:                                                                                                                 |
  |       Thema:    exception and SOAP fault                                                                                     |
  >------------------------------------------------------------------------------------------------------------------------------|



I've been attempting to find documentation on how to have SOAP faults
created from custom exception types on the server, and re-thrown on the
client.

There appear to be several threads on this, none of which have enough
information for me to produce the desired result.  If there is known
documentation on this, can someone please direct me to it?  Otherwise, does
anyone know how to do this?

Desired behavior:

1. Declare a Java class on the server with methods that throw the
appropriate exception type (that preferably inherits from
java.lang.Exception, not AxisFault)
2. Declare the exception class with appropriate get/set methods for all
properties.
3. Whenever necessary, on the server throw an instance of the exception.
4. If necessary configure (using the wsdd file) serializers for the
exception class.
5. If thrown, Axis on the server creates a SOAP fault with sufficient data
that the exception can be re-created on the client side.
6. Generated WSDL contains accurate fault definitions.

So far I've been able to do all of the above except for 5.  The WSDL
appears to be correct, however the fault contains none of the relevant
data.  If the exception class inherits from AxisFault, the fault appears as
follows:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <soapenv:Fault>
   <faultcode>soapenv:Server.generalException</faultcode>
   <faultstring>Internal server error. (ref# 10301)</faultstring>
   <detail>
    <ns1:exceptionName xmlns:ns1="http://xml.apache.org/axis/
">com.maketechnologies.webservice.test.BusinessException</ns1:exceptionName>

   </detail>
  </soapenv:Fault>
 </soapenv:Body>
</soapenv:Envelope>

This causes the client to properly instantiate the BusinessException,
however the BusinessException contains the following information (from
WSDL):

<complexType name="TestException">
  <sequence>
    <element name="message" nillable="true" type="xsd:string" />
  </sequence>
</complexType>
<complexType name="BusinessException">
  <complexContent>
    <extension base="impl:TestException">
      <sequence>
       <element name="errorCode" type="xsd:int" />
      </sequence>
    </extension>
  </complexContent>
</complexType>

As you can see, the errorCode is not transmitted over the wire.

Any help and/or pointers to documentation would be greatly appreciated.

David