You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Sven Zethelius <sv...@expedia.com> on 2011/06/09 01:15:44 UTC

CXF + Camel + JMS Endpoint exception handling

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>


RE: CXF + Camel + JMS Endpoint exception handling

Posted by Sven Zethelius <sv...@expedia.com>.
Sorry, I never went the bean route, so I haven't looked too deeply into the error handlers behavior on it.

-----Original Message-----
From: ychawla [mailto:premiergeneration@yahoo.com] 
Sent: Thursday, February 16, 2012 2:11 PM
To: users@cxf.apache.org
Subject: RE: CXF + Camel + JMS Endpoint exception handling

Hi Sven,
Thanks for the reply.  In my case, I am the client invoking a service that is down (at least in my test it is).  According to the docs, I would be using the OUT phases:

"When a CXF client invokes a CXF server, there is an outgoing interceptor chain for the client"

I can see the exception in the PREPARE_SEND phase but not in any of the subsequent phases.

Do you know of any other way I can get the CXF exception which in this case is a Connection Refused and propogate that to Camel so I can add a deadletter/redelivery strategy on it?

Thanks,
Yogesh 

--
View this message in context: http://cxf.547215.n5.nabble.com/CXF-Camel-JMS-Endpoint-exception-handling-tp4471174p5490886.html
Sent from the cxf-user mailing list archive at Nabble.com.

RE: CXF + Camel + JMS Endpoint exception handling

Posted by ychawla <pr...@yahoo.com>.
Hi Sven,
Thanks for the reply.  In my case, I am the client invoking a service that
is down (at least in my test it is).  According to the docs, I would be
using the OUT phases:

"When a CXF client invokes a CXF server, there is an outgoing interceptor
chain for the client"

I can see the exception in the PREPARE_SEND phase but not in any of the
subsequent phases.

Do you know of any other way I can get the CXF exception which in this case
is a Connection Refused and propogate that to Camel so I can add a
deadletter/redelivery strategy on it?

Thanks,
Yogesh 

--
View this message in context: http://cxf.547215.n5.nabble.com/CXF-Camel-JMS-Endpoint-exception-handling-tp4471174p5490886.html
Sent from the cxf-user mailing list archive at Nabble.com.

RE: CXF + Camel + JMS Endpoint exception handling

Posted by Sven Zethelius <sv...@expedia.com>.
SETUP is an OUT Phase, not an IN Phase.  RECEIVE is the equivalent IN Phase.  The Exchange would be present on the IN since the Exchange is where the message is originating from.  I doubt it would be available on OUT.  Doing a quick scan through CamelConduit, looks like it's not even created until the output stream is closed, which would normally be near the very end of the OUT Phases.

-----Original Message-----
From: ychawla [mailto:premiergeneration@yahoo.com] 
Sent: Thursday, February 16, 2012 1:15 PM
To: users@cxf.apache.org
Subject: RE: CXF + Camel + JMS Endpoint exception handling

Hi Sven,
I changed my phase to:

	public CamelExceptionInterceptor() {
		super(Phase.SETUP);
	}

and now I see the exception, but I can't get the CamelExchange (it is null):

            Exchange exchange = (Exchange) message.get(CxfConstants.CAMEL_EXCHANGE);
            exchange.setException(exception);

I am in the debugger and I see the Camel headers and message information in the CXF Message but I am unable to get the Camel Exchange.

Any ideas?

Thanks,
Yogesh


--
View this message in context: http://cxf.547215.n5.nabble.com/CXF-Camel-JMS-Endpoint-exception-handling-tp4471174p5490748.html
Sent from the cxf-user mailing list archive at Nabble.com.

RE: CXF + Camel + JMS Endpoint exception handling

Posted by ychawla <pr...@yahoo.com>.
Hi Sven,
I changed my phase to:

	public CamelExceptionInterceptor() {
		super(Phase.SETUP);
	}

and now I see the exception, but I can't get the CamelExchange (it is null):

            Exchange exchange = (Exchange)
message.get(CxfConstants.CAMEL_EXCHANGE);
            exchange.setException(exception);

I am in the debugger and I see the Camel headers and message information in
the CXF Message but I am unable to get the Camel Exchange.

Any ideas?

Thanks,
Yogesh


--
View this message in context: http://cxf.547215.n5.nabble.com/CXF-Camel-JMS-Endpoint-exception-handling-tp4471174p5490748.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: CXF + Camel + JMS Endpoint exception handling

Posted by ychawla <pr...@yahoo.com>.
Hi Willem,
I have a similar post on the Camel list and I replied over there:

http://camel.465427.n5.nabble.com/Propogate-CXF-Exception-to-Camel-tc5491102.html#a5491265

I went ahead and re-threw a fault and that propogated to Camel.  Not sure
that's the best way to do it, but it works.

Let me know if I can pitch and assist with the J-Unit test.

Thanks!

Yogesh

--
View this message in context: http://cxf.547215.n5.nabble.com/CXF-Camel-JMS-Endpoint-exception-handling-tp4471174p5491269.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: CXF + Camel + JMS Endpoint exception handling

Posted by Willem Jiang <wi...@gmail.com>.
Hi Yogesh,

Your case is different, as you are not using the camel transport for 
CXF, so you can't get any camel exchange from the message context.

As you are using the one way operation camel may not get the exception, 
I will need to write a simple test case to dig the code for it.


On 2/17/12 3:57 AM, ychawla wrote:
> Hi Sven,
> I think I am seeing the same behavior that you are.  I have a one-way
> service in CXF.  For test purposes, I shut down the service and have the
> client invoke the service through a camel route:
>
>      <camel:route errorHandlerRef="myDeadLetterErrorHandler">
>        <camel:from uri="inputDir"/>
> 		<camel:setHeader
> headerName="operationName"><constant>opName</constant></camel:setHeader>
> 		<camel:setHeader
> headerName="operationNamespace"><constant>opNamespace</constant></camel:setHeader>
> 		<camel:to uri="cxf:bean:myService?dataFormat=PAYLOAD"/>
> 		
>      </camel:route>
>
> I see an error in my logs which I except, but the dead letter error handler
> never gets invoked:
>
> Caused by: java.net.ConnectException: Connection refused
> 	at java.net.PlainSocketImpl.socketConnect(Native Method)[:1.6.0_29]
> 	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)[:1.6.0_29]
> 	at
> java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)[:1.6.0_29]
> 	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)[:1.6.0_29]
> 	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)[:1.6.0_29]
>
> I assume this is because Camel is not getting the exception thrown by CXF. I
> have tried to add an interceptor similar to what you suggest.  However, the
> interceptor never gets invoked (that is why you see it on the in,out,
> infault, and outfault):
>
>
>    <cxf:cxfEndpoint
>      id="myService"
>      address="http://localhost:8080/service"
>      wsdlURL="myService.wsdl"
>      serviceName="test:ServiceService"
>      endpointName="test:Service"
>      xmlns:test="http://www.test.com"
>      >
>      <cxf:inInterceptors>
>      	<ref bean="camelExceptionInterceptor"/>
>      </cxf:inInterceptors>
>      <cxf:outInterceptors>
>      	<ref bean="camelExceptionInterceptor"/>
>      </cxf:outInterceptors>
> 	
>      <cxf:outFaultInterceptors>
>      	<ref bean="camelExceptionInterceptor"/>
>      </cxf:outFaultInterceptors>
>
>    </cxf:cxfEndpoint>
>
> and then I have the bean where I declare it:
>
> <bean id="camelExceptionInterceptor"
> class="org.test.cxf.interceptor.CamelExceptionInterceptor"/>
>
> and then the actual interceptor:
>
> import org.apache.camel.Exchange;
> import org.apache.camel.component.cxf.CxfConstants;
> import org.apache.cxf.interceptor.Fault;
> import org.apache.cxf.message.Message;
> import org.apache.cxf.phase.AbstractPhaseInterceptor;
> import org.apache.cxf.phase.Phase;
>
> public class CamelExceptionInterceptor extends
> AbstractPhaseInterceptor<Message>  {
>
> 	public CamelExceptionInterceptor() {
> 		super(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);
>      }
>
> 	@Override
> 	public void handleMessage(Message message) throws Fault {
> 		// TODO Auto-generated method stub
> 		String hello = "helloWorld";
> 	}
> }
>
> Any idea what I am doing wrong?  My interceptor never gets invoked.  I would
> like to grab the exception from CXF and make the camel exchange aware of it.
>
> If there is an easier way to set up my error handler, that would be great as
> well.
>
> Thanks!
>
> Yogesh
>
>
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/CXF-Camel-JMS-Endpoint-exception-handling-tp4471174p5490565.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>


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

RE: CXF + Camel + JMS Endpoint exception handling

Posted by ychawla <pr...@yahoo.com>.
Hi Sven,
I think I am seeing the same behavior that you are.  I have a one-way
service in CXF.  For test purposes, I shut down the service and have the
client invoke the service through a camel route:

    <camel:route errorHandlerRef="myDeadLetterErrorHandler">
      <camel:from uri="inputDir"/>
		<camel:setHeader
headerName="operationName"><constant>opName</constant></camel:setHeader>
		<camel:setHeader
headerName="operationNamespace"><constant>opNamespace</constant></camel:setHeader>
		<camel:to uri="cxf:bean:myService?dataFormat=PAYLOAD"/>
		
    </camel:route>

I see an error in my logs which I except, but the dead letter error handler
never gets invoked:

Caused by: java.net.ConnectException: Connection refused
	at java.net.PlainSocketImpl.socketConnect(Native Method)[:1.6.0_29]
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)[:1.6.0_29]
	at
java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)[:1.6.0_29]
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)[:1.6.0_29]
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)[:1.6.0_29]

I assume this is because Camel is not getting the exception thrown by CXF. I
have tried to add an interceptor similar to what you suggest.  However, the
interceptor never gets invoked (that is why you see it on the in,out,
infault, and outfault):

   
  <cxf:cxfEndpoint 
    id="myService"
    address="http://localhost:8080/service"
    wsdlURL="myService.wsdl"
    serviceName="test:ServiceService"
    endpointName="test:Service"
    xmlns:test="http://www.test.com"
    >
    <cxf:inInterceptors >
    	<ref bean="camelExceptionInterceptor"/>
    </cxf:inInterceptors>
    <cxf:outInterceptors >
    	<ref bean="camelExceptionInterceptor"/>
    </cxf:outInterceptors>
	
    <cxf:outFaultInterceptors >
    	<ref bean="camelExceptionInterceptor"/>
    </cxf:outFaultInterceptors>

  </cxf:cxfEndpoint>

and then I have the bean where I declare it:

<bean id="camelExceptionInterceptor"
class="org.test.cxf.interceptor.CamelExceptionInterceptor"/>

and then the actual interceptor:

import org.apache.camel.Exchange;
import org.apache.camel.component.cxf.CxfConstants;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;

public class CamelExceptionInterceptor extends
AbstractPhaseInterceptor<Message> {

	public CamelExceptionInterceptor() {
		super(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);
    }

	@Override
	public void handleMessage(Message message) throws Fault {
		// TODO Auto-generated method stub
		String hello = "helloWorld";
	} 
}

Any idea what I am doing wrong?  My interceptor never gets invoked.  I would
like to grab the exception from CXF and make the camel exchange aware of it.  

If there is an easier way to set up my error handler, that would be great as
well.

Thanks!

Yogesh





--
View this message in context: http://cxf.547215.n5.nabble.com/CXF-Camel-JMS-Endpoint-exception-handling-tp4471174p5490565.html
Sent from the cxf-user mailing list archive at Nabble.com.

RE: CXF + Camel + JMS Endpoint exception handling

Posted by Sven Zethelius <sv...@expedia.com>.
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.jiang@gmail.com] 
Sent: Wednesday, June 08, 2011 6:33 PM
To: users@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

RE: CXF + Camel + JMS Endpoint exception handling

Posted by Sven Zethelius <sv...@expedia.com>.
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.jiang@gmail.com] 
Sent: Wednesday, June 08, 2011 6:33 PM
To: users@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

Re: CXF + Camel + JMS Endpoint exception handling

Posted by Willem Jiang <wi...@gmail.com>.
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

Re: CXF + Camel + JMS Endpoint exception handling

Posted by Willem Jiang <wi...@gmail.com>.
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