For now I've written a simple bridging interceptor that forwards the exception 
on to Camel.  I ended up going for a Camel errorHandler instead of 
transactions, but both need the exception exposed to Camel Exchange.  If 
CamelDestination doesn't expose the exception, the errorHandler doesn't get 
triggered and any open transactions don't get rolled back.    With CXF's JMS 
Destination, you are transaction aware, but with CamelDestination it isn't 
since it's not forwarding the exception.

In my case, the operations are one-way so I don't need to worry about 
serializing back the exception, just making sure it is handled or at least 
reported failure (through camel)
        // Phase.RECEIVE
        @Override
        public void handleFault(Message message)
        {
                Exception exception = message.getContent(Exception.class);
                Exchange exchange = (Exchange) 
message.get(CxfConstants.CAMEL_EXCHANGE);
                
                exchange.setException(exception);
        }

I'll probably play with this some more when I need to do two-way operations, 
since I suspect we'll still want Camel to be aware of and handle the exception, 
even if CXF is generating an out fault message, for things like transactions, 
retry and dead message queues.

-----Original Message-----
From: Willem Jiang [mailto:willem.ji...@gmail.com] 
Sent: Wednesday, June 08, 2011 6:33 PM
To: us...@cxf.apache.org
Cc: Sven Zethelius; users@camel.apache.org
Subject: Re: CXF + Camel + JMS Endpoint exception handling

Current Camel transport for CXF just provides a transport tunnel for use 
to use. It can't handle the exception that comes from the service 
implementation.

If you want the camel to handle the application exception, you may 
consider to use camel CXFBean[1] components. BTW you had to marshal the 
exception yourself :)

[1]http://camel.apache.org/cxf-bean-component.html

On 6/9/11 7:15 AM, Sven Zethelius wrote:
> I've started playing with CXF + Camel + JMS, and have set up a sample client 
> and service that can put and get messages from a JMS Queue.
>
> I've started going deeper to understand the transaction and retry logic since 
> one of the use cases I have is to use either the JMS or Camel retry logic to 
> reprocess messages that threw exceptions.  However, after debugging through, 
> it appears the exception the thrown from my service was eaten in 
> ChainedMessageObserver and never gets back to 
> org.apache.camel.component.cxf.transport.CamelDestination.incoming(Exchange). 
>  If I understand the overall flow of the retry logic, Camel needs to see the 
> exception as an exception on the camel Exchange in order to treat the message 
> as failed.  In the CamelDestination (camel-cxf), the cxf Exchange only exists 
> for the CamelDestination.incoming scope, which means the 
> getContent(Exception) is lost with that exchange.  I think the bug is in 
> CamelDestination in that it should be checking the cxf Exchange for 
> getContent(Exception.class) and forwarding it to the camel Exchange so that 
> the rest of Camel can see the Fault.
>
> Is this a bug, or user error and there is another way exceptions should be 
> handled here?  I assume the work around would be a custom CXF interceptor 
> that adds the Exception to camel Exchange.  Any better work arounds?
>
>
>          <jaxws:endpoint id="JMS_prototype.Server"
>                  
> implementor="com.expedia.cc.container.remoting.prototype.SampleServicePortTypeImpl"
>                  
> wsdlLocation="com.expedia.cc.samples.sampleservice.v2.contract.wsdl"
>                  address="${queue}">
>                  <jaxws:properties>
>                          <!-- to force One way messages onto the onMessage 
> thread -->
>                          <entry 
> key="org.apache.cxf.interceptor.OneWayProcessorInterceptor.USE_ORIGINAL_THREAD"
>  value="true" />
>                  </jaxws:properties>
>          </jaxws:endpoint>
>
>          <bean 
> class="org.apache.camel.component.cxf.transport.CamelTransportFactory">
>                  <property name="bus" ref="cxf" />
>                  <property name="camelContext" ref="camelContext" />
>                  <property name="transportIds">
>                          <list>
>                                  
> <value>http://cxf.apache.org/transports/camel</value>
>                          </list>
>                  </property>
>          </bean>
>
>          <bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
>                  <property name="connectionFactory" 
> ref="jmsConnectionFactory.single" />
>                  <property name="useMessageIDAsCorrelationID" value="true" />
>          </bean>
>
>          <camel:camelContext id="camelContext">
>          </camel:camelContext>
>
>


-- 
Willem
----------------------------------
FuseSource
Web: http://www.fusesource.com
Blog:    http://willemjiang.blogspot.com (English)
          http://jnn.javaeye.com (Chinese)
Twitter: willemjiang
Weibo: willemjiang

Reply via email to