Hi,

1) The org.apache.tuscany.sca.binding.jms.ExceptionService interface is 
remotable but the CheckedException is a plain java exception and it doesn't 
follow the JAXWS pattern to represent a fault. In this case, the construction 
of the ChjeckedException is heuristic. 

2) I further debugged the root cause of the null faultInfo. On the following 
stack, it seems that WireFormatJMSTextXMLServiceInterceptor is not doing its 
job to correctly marshal the fault data into the response JMS message. Even 
though the wireFormat is textXML, the TransportServiceInterceptor catches the 
exception, creates a JMSObjectMessage, sets the exception as an Object and 
sends it back as a response. The WireFormatJMSTextXMLServiceInterceptor doesn't 
have a chance to format the fault JMSMessage as textXML.

Thanks,
Raymond

Thread [ActiveMQ Session Task] (Suspended (breakpoint at line 25 in 
ExceptionServiceImpl)) 
 ExceptionServiceImpl.throwChecked() line: 25 
 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available 
[native method] 
 NativeMethodAccessorImpl.invoke(Object, Object[]) line: 79 
 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43 
 Method.invoke(Object, Object...) line: 618 
 JavaImplementationInvoker.invoke(Message) line: 132 
 DataTransformationInterceptor.invoke(Message) line: 78 
 RuntimeWireInvoker.invoke(InvocationChain, Message, RuntimeWire) line: 129 
 RuntimeWireInvoker.invoke(RuntimeWire, Operation, Message) line: 104 
 RuntimeWireInvoker.invoke(Operation, Message) line: 98 
 RuntimeWireInvoker.invoke(Message) line: 86 
 WireFormatJMSTextXMLServiceInterceptor.invoke(Message) line: 68 
 OperationSelectorJMSDefaultServiceInterceptor.invoke(Message) line: 78 
 TransportServiceInterceptor.invoke(Message) line: 77 
 RuntimeWireImpl.invoke(Message) line: 149 
 RRBJMSBindingListener.invokeService(Message) line: 100 
 RRBJMSBindingListener.onMessage(Message) line: 76 
 ActiveMQMessageConsumer.dispatch(MessageDispatch) line: 1021 
 ActiveMQSessionExecutor.dispatch(MessageDispatch) line: 122 
 ActiveMQSessionExecutor.iterate() line: 192 
 PooledTaskRunner.runTask() line: 122 
 PooledTaskRunner$1.run() line: 43 
 ThreadPoolExecutor$Worker.runTask(Runnable) line: 665 
 ThreadPoolExecutor$Worker.run() line: 690 
 Thread.run() line: 810 



From: ant elder 
Sent: Wednesday, January 07, 2009 10:30 AM
To: [email protected] 
Subject: Re: [1.4] Change in Exception handling behaviour for binding.jms


To show what I mean i've committed some fixes in r732415 and r732416 which get 
the testcase working, this isn't a finished fix it just to show where the code 
is going wrong. I haven't looked at the JAXWSFaultExceptionMapper code in any 
detail, should it be dealing with a null faultInfo is is the bug that faultInfo 
isn't getting setup correctly?

   ...ant


On Wed, Jan 7, 2009 at 6:16 PM, ant elder <[email protected]> wrote:

  It turns out its a bit more complicated that that, i think it is the  
FaultException that needs to be returned up the chain so that the databinding 
can transform that back into the user exception, and there is a bug in 
AbstractMessageProcessor either the createFaultMessage or extractPayloadMessage 
needs to pull the FaultException out of the InvocationTargetException, but then 
fixing that the JAXWSFaultExceptionMapper gets an NPE on line 129 as faultInfo 
is null.

  Does that all sound plausible?

     ...ant


  On Wed, Jan 7, 2009 at 5:39 PM, Raymond Feng <[email protected]> wrote:

    IIRC, we intentionally return a FaultException to wrap the user exception 
from the transformation to indicate there is a user fault. The 
extractPayloadMessage should extract the user exception from the FaultException.

    Thanks,
    Raymond


    From: ant elder 
    Sent: Wednesday, January 07, 2009 9:33 AM
    To: Raymond Feng 
    Cc: [email protected] 
    Subject: Re: [1.4] Change in Exception handling behaviour for binding.jms


    OK that helps, but also debugging there you see its too late at that point 
as the service response message sent back from the service already contains the 
wrong exception. Debugging on the service side this is the stack from where it 
goes wrong:

    Thread [ActiveMQ Session Task] (Suspended)    
        DataTransformationInterceptor.invoke(Message) line: 159    
        RuntimeWireInvoker.invoke(InvocationChain, Message, RuntimeWire) line: 
129    
        RuntimeWireInvoker.invoke(RuntimeWire, Operation, Message) line: 104    
        RuntimeWireInvoker.invoke(Operation, Message) line: 98    
        RuntimeWireInvoker.invoke(Message) line: 86    
        WireFormatJMSTextXMLServiceInterceptor.invoke(Message) line: 68    
        OperationSelectorJMSDefaultServiceInterceptor.invoke(Message) line: 78  
  
        TransportServiceInterceptor.invoke(Message) line: 77    
        RuntimeWireImpl.invoke(Message) line: 149    
        RRBJMSBindingListener.invokeService(Message) line: 100    
        RRBJMSBindingListener.onMessage(Message) line: 76    
        ActiveMQMessageConsumer.dispatch(MessageDispatch) line: 1021    
        ActiveMQSessionExecutor.dispatch(MessageDispatch) line: 122    
        ActiveMQSessionExecutor.iterate() line: 192    
        PooledTaskRunner.runTask() line: 122    
        PooledTaskRunner$1.run() line: 43    
        ThreadPoolExecutor$Worker.runTask(Runnable) line: not available    
        ThreadPoolExecutor$Worker.run() line: not available    
        Thread.run() line: not available    

    Before DataTransformationInterceptor.invoke(Message) line: 159 is run the 
"result" variable contains the correct original application exception and thats 
what we'd like gets sent back to the clinet, but after transformException is 
called at line 160 "newResult" is a 
org.apache.tuscany.sca.interfacedef.util.FaultException instance and that is 
whats returned to the client.

    Is this related to the value of sourceFaultType which is:

    sourceFaultType    DataTypeImpl<L>  (id=265)    
        dataBinding    "org.apache.axiom.om.OMElement" (id=282)    
        genericType    Class<T> (java.lang.Object) (id=9)    
        logical    XMLType  (id=298)    
        metaDataMap    null    
        physical    Class<T> (java.lang.Object) (id=9)    

    perhaps thats not correct with the way all the wireformats and databindings 
are working now for JMS where really is just wanting to send back the 
application exception in the response message?

       ...ant



    On Wed, Jan 7, 2009 at 4:40 PM, Raymond Feng <[email protected]> wrote:

      Hi,

      I debugged the test case and found the code on the following stack is 
problematic:

      org.osoa.sca.ServiceRuntimeException: remote service exception, see 
nested exception
      at 
org.apache.tuscany.sca.binding.jms.provider.AbstractMessageProcessor.extractPayloadFromJMSMessage(AbstractMessageProcessor.java:92)
      at 
org.apache.tuscany.sca.binding.jms.wireformat.jmstextxml.runtime.WireFormatJMSTextXMLReferenceInterceptor.invokeResponse(WireFormatJMSTextXMLReferenceInterceptor.java:107)
      at 
org.apache.tuscany.sca.binding.jms.wireformat.jmstextxml.runtime.WireFormatJMSTextXMLReferenceInterceptor.invoke(WireFormatJMSTextXMLReferenceInterceptor.java:82)
      at 
org.apache.tuscany.sca.binding.jms.provider.RRBJMSBindingInvoker.invoke(RRBJMSBindingInvoker.java:201)
      at 
org.apache.tuscany.sca.core.databinding.wire.DataTransformationInterceptor.invoke(DataTransformationInterceptor.java:78)
      at 
org.apache.tuscany.sca.core.invocation.JDKInvocationHandler.invoke(JDKInvocationHandler.java:287)
      at 
org.apache.tuscany.sca.core.invocation.JDKInvocationHandler.invoke(JDKInvocationHandler.java:154)
      at $Proxy21.throwChecked(Unknown Source)
      at 
org.apache.tuscany.sca.binding.jms.ExceptionServiceClient.throwChecked(ExceptionServiceClient.java:38)

      When the JMSMessage contains a fault (user exception), the 
AbstractMessageProcessor.extractPayloadFromJMSMessage() method should not throw 
a ServiceRuntimeException, instead it should call Message.setFaultBody with the 
user exception extracted from the FaultException.

      public Object extractPayloadFromJMSMessage(Message msg) {
        try {
                if (msg.getBooleanProperty(JMSBindingConstants.FAULT_PROPERTY)) 
{
                    // ----------------- [rfeng] This is wrong 
----------------------
                    throw new ServiceRuntimeException("remote service 
exception, see nested exception", (Throwable)((ObjectMessage)msg).getObject());
                }
            } catch (JMSException e) {
            throw new JMSBindingException(e);
        }
        return extractPayload(msg);
      }

      Thanks,
      Raymond


      From: ant elder
      Sent: Wednesday, January 07, 2009 4:24 AM
      To: [email protected]
      Subject: Re: [1.4] Change in Exception handling behaviour for binding.jms 






      On Wed, Jan 7, 2009 at 11:12 AM, Dave Sowerby <[email protected]> 
wrote:

      Hey guys,

      I'm trying to upgrade an application from Tuscany 1.3.2 to 1.4 RC4,
      the application uses binding.jms and I've noticed a marked change in
      behaviour for Exception handling - could someone tell me if this is
      expected and if there is any means of getting a handle on the original
      Exception?

      Basically, the service throws a UserException with a message, but on
      the client side I get the following Exception hierarchy:

      org.osoa.sca.ServiceRuntimeException
       -> org.osoa.sca.ServiceRuntimeException
         -> java.lang.reflect.InvocationTargetException
            -> org.apache.tuscany.sca.interfacedef.util.FaultException

      Where the FaultException contains the original message from the 
UserException.

      Back in 1.3.2, for Exceptions the client would have a reconsituted
      equivilant of the original Exception thrown.

      Any guidance would be greatly appreciated,

      Cheers,

      Dave.


      That sounds like http://issues.apache.org/jira/browse/TUSCANY-2593 which 
sadly although marked as a blocker didn't get fixed in the 1.4 RC.

      The problem is due to the way the DataTransformationInterceptor handles 
the exception is different now so the way the JMS binding returns the service 
exception doesn't get returned to the client as before. Tracing through the 
code i can get it to DataTransformationInterceptor line 147 where the 
sourceDataType gets set to 
org.apache.tuscany.sca.interfacedef.util.FaultException which is what the 
transform on line 159 produces so the original exception from the remote 
service is lost.

      There's quite a few FIXME comments around here in the 
DataTransformationInterceptor so i'm not sure how this is supposed to work, 
you'd think it must be common across all bindings - does any one know is there 
a fixed way a binding can return an application checked exception object and 
have the data binding framework just return that to the client?

       ...ant 





Reply via email to