I'm deploying web services using EJB Provider and services are implemented by Session Beans.
Methods are declared to throw some exceptions, but those exceptions doesn't extend AxisFault because I don't want EJB clients depend on Axis.
So to build a Java client for those services WSDL2Java is used and then exception classes are generated to be used at the client side.
Let's say this is a method at the server side:
/** * @ejb.interface-method * @axis.method */ public void mymethod() throws BaseException {
... throw new DerivedException(); ... }
where DerivedException extends BaseException, and BaseException just extends Exception. Note that only BaseException is included in the signature of mymethod().
This is (more or less) the XML fragment of fault detail in the response:
<detail> <BaseException xsi:type="DerivedException".....> ..... </detail>
The proper OperationDesc at the client stub doesn't contain DerivedException to be a fault of mymethod(). It depends on axis version, but in general it can't find DerivedException to be the right class to instantiate and AxisFault or BaseException is just thrown, and not the proper exception (DerivedException).
Current (1.21) SOAPFaultDetailBuilder.java:onStartChild() in CVS tries to find the right class using the xsi:type attribute value (DerivedException in this example), that is not found in the OperationDesc, then using the qname (BaseException in the example, which is used) and if finally no proper class is found in the OperationDesc, then TypeMapping of current context is used.
In my example, if no OperationDesc is set at the client side the right exception is raised (DerivedException) because the stub looks just in the TypeMapping; but not using OperationDesc no type check will be done when calling the service.
Test case in Axis 1.1 works because exception at the server side extends AxisFault, and then typeName kludge is used.
To solve this problem I suggest this:
Don't try to get the class to instantiate by looking at the qname, but just use the xsi:type attribute to look for its value in the OperationDesc and if not found finally look at the TypeMapping.
Maybe I'm missing something?
TIA
Adrian P.J.