Hi,
 
 
I have been using custom exceptions for nearly 2 years now and it always worked fine for me (since 1.2-RC2 I think).
 
But I start from the WSDL and have the java classes generated. I find it easier to maintain 1 file and have 30 java classes generated than the opposite. Once you understand a WSDL it is really easy to add parameters and operations.
 
 
so my custom exception structure is:
 <complexType name="WSException">
  <sequence>
   <element name="errorCode" type="xsd:int" nillable="false"/>
   <element name="errorMessage" type="xsd:string" nillable="true"/>
   <element name="trace" type="xsd:string" nillable="true"/>
  </sequence>
 </complexType>
 
I get the flowwing generated for me:
public class WSException  extends org.apache.axis.AxisFault  implements java.io.Serializable {...}
 
And then when I use axis as a client too, the method throws back that exception that I can catch directly (nothing to cast).
 
 
However there can be a small problem. Since I have a lot of WebServices, I wanted to reuse the WSException in all of them, so I defined it in its own XSD file, in its own namespace. ie: the exception is defined in namespace A and the WebService namespace is B.
When the exception is returned, the namespace is A, when it should be B (because the operation is in B, it is in the SOAP standard). So I had to define a new constructor to override this problem:
 
    public WSException(String namespace) {
     super(new javax.xml.namespace.QName(namespace, "WSException"), null, null, null);
    }
 
Since I use axis 1.2-RC3 to generate my java classes, I don't know if this problem has been fixed in later versions.
 
 
I use Axis, gSOAP and ActiveBPEL and all of them can handle my custom exception.
 
 
Hope it can help,
Daniel
 

 
On 8/4/06, Eric Borisow <[EMAIL PROTECTED]> wrote:
Derek,

Thanks for the reply, but I have found the answer.  I
found most of the answer in the Axis samples\faults
directory, but they leave out some info.  I will post
what I found so it will hopefully help someone else.

1. Your Exception should extend Exception and not
RemoteException.

This should be done for a few reasons:
a) It is the approach that the samples use.
b) You probably would rather extend Exception than
RemoteException as a general programming practice.
c) I, personally, did not seem to get this working if
I used RemoteException.  Axis gives you a
RemoteException that is your class, but I could not
find a way to correctly cast it back to my Exception.

2. Your Exception must have a constructor that accepts
all of the properties to be set.

There is a technical reason here that I read in one of
the posts out there, but I can't remember where it is.
It was something about Axis needing to be able to set
these properties in the Constructor and not in a
setter.  Here is my sample Exception:

import java.io.Serializable;

public class TestException extends Exception
implements Serializable
{
   private String someError;

   public TestException() {}

   public TestException(String someError)
   {
       this.someError = someError;
   }

   public String getSomeError()
   {
       return this.someError;
   }

   public void setSomeError(String someError)
   {
       this.someError = someError;
   }

}

3. Your service should throw RemoteException and the
custom Exception.

Here is a sample:

import java.rmi.RemoteException;

public interface IServiceTest
{
   public void throwError() throws RemoteException,
TestException;
}

4. Catch AxisFault in your client.

If you're using the stubs generated by Axis, you don't
need to worry about this, but if you're using what I
like to call the manual method, then you need to catch
it as an AxisFault.

Here is the sample code:

import java.io.StringWriter;
import java.net.URL;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry ;

import org.apache.axis.AxisFault;
import
org.apache.axis.encoding.ser.BeanDeserializerFactory;
import
org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.apache.xml.serialize.OutputFormat ;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.spx.services.TestException;

public class ManualServiceTest
{

   /**
    * @param args
    */
   public static void main(String[] args)
   {
       try
       {
           ServiceFactory serviceFactory =
ServiceFactory.newInstance();
           Service service =
serviceFactory.createService(new
QName("urn:axisexceptiontest", "ServiceService"));
           Call     call    = (Call)
service.createCall();
           String endpointURL =
" http://localhost:8080/axisexceptiontest/services/axisexceptiontest";


           call.setTargetEndpointAddress(new
URL(endpointURL).toString());
           call.setOperationName( new
QName("urn:axisexceptiontest", "throwError") );

           TypeMappingRegistry registry =
service.getTypeMappingRegistry();
           TypeMapping map =
registry.getDefaultTypeMapping();

                       // Don't forget to register your exception!!!
           QName faultQName = new
QName("urn:axisexceptiontest", "TestException");
           map.register(TestException.class,
                                               faultQName,
                                               new BeanSerializerFactory(TestException.class,
faultQName),
                                               new BeanDeserializerFactory(TestException.class,
faultQName));

           call.invoke(new Object[] { });
       }
               catch(AxisFault fault)
               {
           System.out.println("Error type is Axis
Fault");

           System.out.println ("Fault actor : "+
fault.getFaultActor());
           System.out.println("Fault string: "+
fault.getFaultString());
           System.out.println("Fault reason: "+
fault.getFaultReason ());
           System.out.println("Fault code: "+
fault.getFaultCode());

           Object cause = fault.getCause();
           if (cause != null)
           {
               System.out.println ("Class of cause is:
" + cause.getClass().getName());
               if (cause instanceof TestException)
               {
                   TestException myEx =
(TestException) cause;
                   System.out.println("Error message
from my exception: " + myEx.getSomeError());
               }
           }
               }
       }
}

Finally, here was my server-config.wsdd:

<?xml version=" 1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java=" http://xml.apache.org/axis/wsdd/providers/java">
<globalConfiguration>
<parameter name="adminPassword" value="admin"/>
<parameter name="sendMultiRefs" value="false"/>
<parameter name="sendXsiTypes" value="true"/>
<parameter name="sendXMLDeclaration" value="true"/>
<parameter name="dotNetSoapEncFix" value="true"/>
</globalConfiguration>
<handler name="LocalResponder"
type="java:org.apache.axis.transport.local.LocalResponder"/>
<handler name="URLMapper"
type="java:org.apache.axis.handlers.http.URLMapper "/>
<handler name="Authenticate"
type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
<handler name="MsgDispatcher"
type="java:org.apache.axis.providers.java.MsgProvider "/>
<handler name="RPCDispatcher"
type="java:org.apache.axis.providers.java.RPCProvider"/>

<service name="axisexceptiontest" provider="java:RPC"
style="rpc" use="encoded">
<parameter name="allowedMethods" value="*"/>
<parameter name="wsdlPortType" value="Service"/>
<parameter name="className"
value="com.spx.services.Service "/>
<parameter name="wsdlServicePort"
value="axisexceptiontest"/>
<parameter name="wsdlTargetNamespace"
value="urn:axisexceptiontest"/>
<parameter name="wsdlServiceElement"
value="ServiceService"/>
<beanMapping qname="ns:TestException"
               xmlns:ns="urn:axisexceptiontest"

languageSpecificType="java:com.spx.services.TestException "/>

</service>
<service name="AdminService" provider="java:MSG">
<parameter name="allowedMethods"
value="AdminService"/>
<parameter name="enableRemoteAdmin" value="true"/>
<parameter name="className"
value="org.apache.axis.utils.Admin"/>

<namespace>http://xml.apache.org/axis/wsdd/</namespace>
</service>
<service name="Version" provider="java:RPC">
<parameter name="allowedMethods"
value="getVersion"/>
<parameter name="className"
value="org.apache.axis.Version"/>
</service>
<transport name="http">
<requestFlow>
  <handler type="URLMapper"/>
  <handler
type="java:org.apache.axis.handlers.http.HTTPAuthHandler "/>
</requestFlow>
</transport>
<transport name="local">
<responseFlow>
  <handler type="LocalResponder"/>
</responseFlow>
</transport>
</deployment>

I hope this helps someone else.

Thanks,
Eric


--- Derek <[EMAIL PROTECTED]> wrote:

> In general, you cannot send arbitrary exceptions to
> remote clients, since
> Axis (or most other client/server communication
> protocols) has no idea how
> to serialize/deserialize an arbitrary exception that
> you might have created
> so that it can be transmitted to a remote client.
> You should probably only
> be sending subclasses of RemoteException, and
> probably should include very
> limited, if any, additional information in the
> exception class itself. I
> suggest that you make sure that your TestException
> extends RemoteException,
> not just Exception.
>
> I am not sure how this works if a RemoteException
> has a 'cause' field which
> is not a RemoteException. I am not an expert in what
> RemoteException is
> capable of, but I think I know enough to understand
> that what you are trying
> to do (throw an exception that is not derived from
> RemoteException from
> server to client) is not, in general, possible.
>
> Derek
>
>
>
> > -----Original Message-----
> > From: Eric Borisow [mailto:[EMAIL PROTECTED]]
> > Sent: Thursday, August 03, 2006 6:33 AM
> > To: [email protected]
> > Subject: Re: Question about handling custom
> exceptions in Axis 1.3
> >
> >
> > I tried using this line:
> >
> > TestException myEx = (TestException) gbe;
> >
> > But, it won't even compile.  It gives me the
> error:
> > Cannot cast from RemoteException to TestException.
>  Is
> > there something I am missing?
> >
> > Thanks,
> > Eric
> >
> > --- xu cai <[EMAIL PROTECTED]> wrote:
> >
> > > AxisFault extends from RemoteException, I think
> you
> > > can simply cast
> > > RemoteException to your customized exception.
> hope
> > > it works.
> > >
> > > -jeff
> > >
> > >
> > > On 8/3/06, Eric Borisow <[EMAIL PROTECTED]>
> wrote:
> > > >
> > > > Hi,
> > > >
> > > > I have been trying to piece together the best
> way
> > > to
> > > > generate and consume a custom exception with
> Axis
> > > > 1_3.  I have created a test with an interface,
> a
> > > > service implementation of the interface and an
> > > > Exception.
> > > >
> > > > When I generate the wsdl using java2wsdl, the
> wsdl
> > > > contains a reference to the TestException
> class as
> > > a
> > > > fault of the service.  When I call the
> service, it
> > > > returns an AxisFault containing information
> about
> > > the
> > > > fault.  My question is... what can I do with
> that
> > RemoteException to
> > > > get my exception out of it?  I
> > > have
> > > > seen some other articles where it seems you
> should
> > > > just be able to catch your custom exception
> but
> > > all I
> > > > ever get is RemoteException which I then have
> to
> > > > convert to an AxisFault but I still don't get
> > > access
> > > > to my exception per se.  See below for my
> code.
> > > >
> > > > Thanks,
> > > > Eric
> > > >
> > > > Interface:
> > > >
> > > > public interface IServiceTest
> > > > {
> > > >    public void throwError() throws
> TestException;
> > > > }
> > > >
> > > > Service implementation:
> > > >
> > > > public class Service implements IServiceTest
> > > > {
> > > >
> > > >    public void throwError() throws
> TestException
> > > >    {
> > > >        throw new TestException();
> > > >    }
> > > >
> > > > }
> > > >
> > > > Exception:
> > > >
> > > > import java.io.Serializable;
> > > >
> > > > public class TestException extends Exception
> > > > implements Serializable
> > > > {
> > > >    private String someError;
> > > >
> > > >    public TestException() {}
> > > >
> > > >    public TestException(String someError)
> > > >    {
> > > >        this.someError = someError;
> > > >    }
> > > >
> > > >    public String getSomeError()
> > > >    {
> > > >        return someError;
> > > >    }
> > > >
> > > >    public void setSomeError(String someError)
> > > >    {
> > > >        this.someError = someError;
> > > >    }
> > > >
> > > >
> > > > }
> > > >
> > > > wsdl:
> > > >
> > > > <?xml version="1.0" encoding="UTF-8"?>
> > > > <wsdl:definitions
> > > > targetNamespace="http://services.spx.com "
> > > > xmlns:impl="http://services.spx.com"
> > > > xmlns:intf="http://services.spx.com"
> > > >
> xmlns:apachesoap="http://xml.apache.org/xml-soap"
> > > >
> > >
> >
>
xmlns:wsdlsoap=" http://schemas.xmlsoap.org/wsdl/soap/"
> > > >
> > >
> >
>
xmlns:soapenc=" http://schemas.xmlsoap.org/soap/encoding/"
> > > > xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> > > > xmlns:wsdl=" http://schemas.xmlsoap.org/wsdl/">
> > > > <!--WSDL created by Apache Axis version: 1.3
> > > > Built on Oct 05, 2005 (05:23:37 EDT)-->
> > > > <wsdl:types>
> > > > <schema
> xmlns="http://www.w3.org/2001/XMLSchema"
> > > > targetNamespace="http://services.spx.com ">
> > > >   <import
> > > >
> > >
> >
>
namespace="http://schemas.xmlsoap.org/soap/encoding/ "/>
> > > >   <complexType name="TestException">
> > > >    <sequence>
> > > >     <element name="someError" nillable="true"
> type="xsd:string"/>
> > > >    </sequence>
> > > >   </complexType>
> > > > </schema>
> > > > </wsdl:types>
> > > >   <wsdl:message name="TestException">
> > > >      <wsdl:part name="fault"
> > > > type="impl:TestException"/>
> > > >   </wsdl:message>
> > > >   <wsdl:message name="throwErrorRequest">
>
=== message truncated ===


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Reply via email to