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]

Reply via email to