views:

3029

answers:

3

Hi, I'm actually developing a Web Service in Java using Axis 2. I designed my service as a POJO (Plain Old Java Object) with public method throwing exceptions :

public class MyService {
   public Object myMethod() throws MyException {
        [...]
   }
}

I then generated the WSDL using Axis2 ant task. With the WSDL I generate a client stub to test my service. The generated code contains a "MyExceptionException" and the "myMethod" in the stub declare to throw this :

public class MyServiceStub extends org.apache.axis2.client.Stub {
    [...]
    public MyServiceStub.MyMethodResponse myMethod(MyServiceStub.MyMethod myMethod)
    throws java.rmi.RemoteException, MyExceptionException0 {
        [...]
    }
    [...]
}

But when calling the method surrounded by a catch, the "MyExceptionException" is never transmitted by the server which transmit an AxisFault instead (subclass of RemoteException).

I assume the problem is server-side but don't find where. The service is deployed as an aar file in the axis2 webapp on a tomcat 5.5 server. The services.xml looks like this :

<?xml version="1.0" encoding="UTF-8"?>
<service name="MyService" scope="application">
    <description></description>
    <messageReceivers>
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" 
            class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
           class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
    <parameter name="ServiceClass">MyService</parameter>
    <parameter name="ServiceTCCL">composite</parameter>
</service>

If the behavior is normal then I'll drop the use of Exceptions (which is not vital to my project) but I'm circumspect why Java2WSDL generate custom <wsdl:fault> in operation input & output declaration and WSDL2Java generate an Exception class (and declare to throw it in the stub method) if this is not usable...

+1  A: 

I don't really think there is a problem. Your Client calls a method on the server. That method results in an exception. Axis transforms this exception to something which can be send to the client to indicate the error.

All exceptions, as far as I know, are wrapped into an AxisFault which is then transmitted to the client as, I believe, a SoapFault message with as description the exception message.

In other words, the client should only see AxisFaults as the exception (exception class) is not serialized and send. Server exceptions should become AxisFaults at the client side.

extraneon
In the server-side generated code, it generate an AxisFault and add to the SOAP context a org.apache.axis2.Constants.FAULT_NAME to map the custom fault in the WSDL...
Vinze
In the client stub, the problem seem to be that org.apache.axiom.om.OMElement faultElt = f.getDetail(); returns null... so the stub isn't able to map the axis fault to a custom java exception (which is generated from WSDL)...
Vinze
+1  A: 

Have you tried using Axis2 with Lady4j, it solved this issue for us.

Axel
A: 

If your WSDL specifies that your service throws a custom error your client should expect to handle these errors as well as the generic remote exceptions thrown by the operation of Axis2.

When your stub recieves an AxisFault from the server, it attempts to consturct a custom exception if this is specified in your WSDL. If this fails it will simply pass out the AxisFault instead.

The stub will attempt to call f.getDetail(). If this is null it will not try to construct a custom exception and will pass out the AxisFault. With Axis2 1.5, the autogenerated MessageInOutReciver on the serverside does not set this value by default.

You can set it manually on the serverside like this (assuming you have autogenerated MyFaultException and MyFault classes):

        MyFaultException ex = new MyFaultException("My Exception Message");
        MyFault fault = new MyFault();
        fault.setMyFault("My Fault Message");
        ex.setFaultMessage(fault);
        throw ex; 
Russell