AxisFault.makeFault() modification required to unwrap Proxy-raised
UndeclaredThrowableExceptions.
-------------------------------------------------------------------------------------------------
Key: AXIS2-1853
URL: http://issues.apache.org/jira/browse/AXIS2-1853
Project: Apache Axis 2.0 (Axis2)
Issue Type: Improvement
Components: kernel
Affects Versions: 1.1
Environment: OS Independent
Reporter: Richard Gruet
PROBLEM:
When a WS implementation throws an Exception which is not "official", i.e. NOT
declared in the WSDL for the operation and therefore not declared as an
Exception thrown by the operation in the SEI, it is caught by the
MessageReceiver generated by Axis2 for the service (in my case an
AbstractInOutSyncMessageReceiver), and the static method AxisFault.makeFault()
is called to "wrap" the exception into a legal AxisFault :
...
catch (Exception e) {
throw org.apache.axis2.AxisFault.makeFault(e);
}
The method AxisFault.makeFault() handles specially InvocationTargetException
instances so to "unwrap" them:
public static AxisFault makeFault(Exception e) {
if (e instanceof InvocationTargetException) {
Throwable t = ((InvocationTargetException) e).getTargetException();
if (t instanceof Exception) {
e = (Exception) t;
}
}
...
But another category of "wrapped" exceptions exist, which is not handled by
this method: exceptions of class UndeclaredThrowableException, returned by
method invoke() of the [java.lang.reflect.]InvocationHandler of a
[java.lang.reflect.]Proxy. The wrapped exception is available by calling method
getCause() on the UndeclaredThrowableException instance.
So when the WS implementation is a Proxy and an "unofficial" exception is
thrown, makeFault() doesn't accurately reflects the target exception and the
resulting SOAP fault is not helpful since it justs says
"UndeclaredThrowableException" as the cause of the fault.
SUGGESTED SOLUTION:
The solution is very easy to implement and backward compatible: just add a
paragraph in AxisFault.makeFault() to handle the case:
...
else if (e instanceof UndeclaredThrowableException) {
Throwable t = ((UndeclaredThrowableException) e).getCause();
if (t instanceof Exception) {
e = (Exception) t;
}
}
.. So the entire modified makeFault() method would now look like:
/**
* Make an AxisFault based on a passed Exception. If the Exception is
* already an AxisFault, simply use that. Otherwise, wrap it in an
* AxisFault. If the Exception is an InvocationTargetException or an
* UndeclaredThrowableException (which already wrap another Exception), get
* the wrapped Exception out from there and use that instead of the passed
* one.
*
* @param e
* the <code>Exception</code> to build a fault for
* @return an <code>AxisFault</code> representing <code>e</code>
*/
public static AxisFault makeFault(Exception e) {
if (e instanceof InvocationTargetException) {
Throwable t = ((InvocationTargetException) e).getTargetException();
if (t instanceof Exception) {
e = (Exception) t;
}
}
else if (e instanceof UndeclaredThrowableException) {
Throwable t = ((UndeclaredThrowableException) e).getCause();
if (t instanceof Exception) {
e = (Exception) t;
}
}
if (e instanceof AxisFault) {
return (AxisFault) e;
}
return new AxisFault(e);
}
I personnaly need this modification because I'm using a Proxy implementation in
order to perform a number of cross-cutting features, including input parameter
validation for which I need to return a significant fault message to the client
when parameters are invalid.
Richard
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]