On Wed, Aug 4, 2010 at 6:19 AM, Jim Newsham <[email protected]> wrote: > > Hi Willem, > > Thanks for the fast reply. After adding the transferException option to the > jms url on both the client and the server, I am now seeing the exception > propagate to the client. The only remaining problem is that the exception > thrown by the remote service (i.e., LoginException) is wrapped in a > RuntimeCamelException. I am sure I could write my own proxy implementation > that unwraps the exception without too much trouble, but I am wondering if > this is something that Camel's proxy should do on its own. What do you > think? >
It has to be a runtime exception because a checked exception can only be thrown if the method signature have declared it. And we have no logic which unwraps and checks against the method signature to see if its a declared exception. Maybe we could add such logic. Fell free to create a JIRA ticket. > Thanks, > Jim > > On 8/3/2010 4:55 PM, Willem Jiang wrote: >> >> Hi, >> >> You are using activemq component to make Client and Server talk to each >> other. Please set the option transferException=true on your activemq >> endpoint, the default value of this option is false. >> >> Here is note for it which is token from Camel JMS wiki[1]. >> "Camel 2.0: If enabled and you are using Request Reply messaging (InOut) >> and an Exchange failed on the consumer side, then the caused Exception will >> be send back in response as a javax.jms.ObjectMessage. If the client is >> Camel, the returned Exception is rethrown. This allows you to use Camel JMS >> as a bridge in your routing - for example, using persistent queues to enable >> robust routing. Notice that if you also have transferExchange enabled, this >> option takes precedence. The caught exception is required to be >> serializable. The original Exception on the consumer side can be wrapped in >> an outer exception such as org.apache.camel.RuntimeCamelException when >> returned to the producer." >> >> [1]http://camel.apache.org/jms.html >> >> Willem >> ---------------------------------- >> Apache Camel, Apache CXF committer >> Open Source Integration http://www.fusesource.com >> Blog http://willemjiang.blogspot.com >> Tiwtter http://twitter.com/willemjiang >> >> >> Jim Newsham wrote: >>> >>> I'm pretty new to Camel, and I'm a little confused about exception >>> handling. I'm working on a client/server application whose communication >>> happens over camel/jms. I'm taking advantage of Camel's bean invocation >>> support so that the client can invoke remote services which are exported by >>> the server (similar to rmi, spring remoting, etc.). Implemented this way, >>> it seems pretty trivial, but one thing which is not working is propagation >>> of service call exceptions from the server to the client. >>> >>> A brief description of the setup: >>> >>> // the service interface common to both client and server >>> interface LoginService { >>> public String login(String username, String password) throws >>> LoginException; >>> } >>> >>> on the server: >>> LoginService loginService = new LoginServiceImpl(); >>> ... >>> // server routes >>> from("activemq:queue:loginService") >>> .bean(loginService); >>> >>> on the client: >>> // client routes >>> from("direct:loginService") >>> .to("activemq:queue:loginService") >>> ... >>> // elsewhere, I construct the remote service proxy >>> Endpoint endpoint = context.getEndpoint("direct:loginService"); >>> LoginService loginService = ProxyHelper.createProxy(endpoint, >>> LoginService.class); >>> >>> >>> This setup works as desired in the case where LoginService.login() >>> completes normally. However, in the case where LoginService.login() throws >>> an exception, an error is logged on the server (see below), and the client >>> gets no response (the client times out after receiving no response for 20s). >>> I haven't configured any exception handler, so it's using the default >>> exception handler, which is supposed to "propagate the exception to the >>> caller". Well, I don't really understand what "propagate the exception to >>> the caller" is supposed to mean in the context of camel, but it sure isn't >>> propagating the call back to the remote invoker. Is there some specific >>> error handler recipe that I need to use here? I'm using Camel 2.3.0. >>> >>> Thanks, >>> Jim >>> >>> >>> 2010-08-03 15:59:21,147 [DefaultMessageListenerContainer-1] INFO route2 >>> - Received login request: >>> 2010-08-03 15:59:21,163 [DefaultMessageListenerContainer-1] ERROR >>> org.apache.camel.processor.DefaultErrorHandler - Failed delivery for >>> exchangeId: ID:rsi-eng-newsham-54650-1280887160851-0:0:2:1:1. Exhausted >>> after delivery attempt: 1 caught: org.apache.camel.RuntimeCamelException: >>> javax.security.auth.login.LoginException: invalid username or password >>> org.apache.camel.RuntimeCamelException: >>> javax.security.auth.login.LoginException: invalid username or password >>> at >>> org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1111) >>> at >>> org.apache.camel.component.bean.BeanInvocation.invoke(BeanInvocation.java:92) >>> at >>> org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:105) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.processor.DelegateProcessor.processNext(DelegateProcessor.java:53) >>> at >>> org.apache.camel.processor.DelegateProcessor.proceed(DelegateProcessor.java:82) >>> at >>> org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:97) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.processExchange(RedeliveryErrorHandler.java:185) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:151) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:89) >>> at >>> org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:49) >>> at >>> org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:228) >>> at org.apache.camel.processor.Pipeline.process(Pipeline.java:75) >>> at >>> org.apache.camel.processor.UnitOfWorkProcessor.processNext(UnitOfWorkProcessor.java:70) >>> at >>> org.apache.camel.processor.DelegateProcessor.process(DelegateProcessor.java:48) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:84) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:543) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:482) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:451) >>> at >>> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:323) >>> at >>> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:261) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:974) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:876) >>> at java.lang.Thread.run(Thread.java:619) >>> Caused by: javax.security.auth.login.LoginException: invalid username or >>> password >>> at >>> com.referentia.sdf.csproto.node.components.ClientGatewayComponent$LoginServiceImpl.login(ClientGatewayComponent.java:205) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at >>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>> at >>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>> at java.lang.reflect.Method.invoke(Method.java:597) >>> at >>> com.referentia.commons.lang.reflect.RetargettableProxy$Handler.invoke(RetargettableProxy.java:236) >>> at $Proxy12.login(Unknown Source) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at >>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>> at >>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>> at java.lang.reflect.Method.invoke(Method.java:597) >>> at >>> org.apache.camel.component.bean.BeanInvocation.invoke(BeanInvocation.java:86) >>> ... 25 more >>> 2010-08-03 15:59:21,164 [DefaultMessageListenerContainer-1] ERROR >>> org.apache.camel.component.jms.EndpointMessageListener - Caused by: >>> [org.apache.camel.RuntimeCamelException - >>> javax.security.auth.login.LoginException: invalid username or password] >>> org.apache.camel.RuntimeCamelException: >>> javax.security.auth.login.LoginException: invalid username or password >>> at >>> org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1111) >>> at >>> org.apache.camel.component.bean.BeanInvocation.invoke(BeanInvocation.java:92) >>> at >>> org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:105) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.processor.DelegateProcessor.processNext(DelegateProcessor.java:53) >>> at >>> org.apache.camel.processor.DelegateProcessor.proceed(DelegateProcessor.java:82) >>> at >>> org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:97) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.processExchange(RedeliveryErrorHandler.java:185) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:151) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:89) >>> at >>> org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:49) >>> at >>> org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:228) >>> at org.apache.camel.processor.Pipeline.process(Pipeline.java:75) >>> at >>> org.apache.camel.processor.UnitOfWorkProcessor.processNext(UnitOfWorkProcessor.java:70) >>> at >>> org.apache.camel.processor.DelegateProcessor.process(DelegateProcessor.java:48) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:84) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:543) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:482) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:451) >>> at >>> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:323) >>> at >>> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:261) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:974) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:876) >>> at java.lang.Thread.run(Thread.java:619) >>> Caused by: javax.security.auth.login.LoginException: invalid username or >>> password >>> at >>> com.referentia.sdf.csproto.node.components.ClientGatewayComponent$LoginServiceImpl.login(ClientGatewayComponent.java:205) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at >>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>> at >>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>> at java.lang.reflect.Method.invoke(Method.java:597) >>> at >>> com.referentia.commons.lang.reflect.RetargettableProxy$Handler.invoke(RetargettableProxy.java:236) >>> at $Proxy12.login(Unknown Source) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at >>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>> at >>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>> at java.lang.reflect.Method.invoke(Method.java:597) >>> at >>> org.apache.camel.component.bean.BeanInvocation.invoke(BeanInvocation.java:86) >>> ... 25 more >>> 2010-08-03 15:59:21,218 [DefaultMessageListenerContainer-1] WARN >>> org.springframework.jms.listener.DefaultMessageListenerContainer - >>> Execution of JMS message listener failed >>> org.apache.camel.RuntimeCamelException: >>> javax.security.auth.login.LoginException: invalid username or password >>> at >>> org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1111) >>> at >>> org.apache.camel.component.bean.BeanInvocation.invoke(BeanInvocation.java:92) >>> at >>> org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:105) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.processor.DelegateProcessor.processNext(DelegateProcessor.java:53) >>> at >>> org.apache.camel.processor.DelegateProcessor.proceed(DelegateProcessor.java:82) >>> at >>> org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:97) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.processExchange(RedeliveryErrorHandler.java:185) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:151) >>> at >>> org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:89) >>> at >>> org.apache.camel.processor.DefaultErrorHandler.process(DefaultErrorHandler.java:49) >>> at >>> org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:228) >>> at org.apache.camel.processor.Pipeline.process(Pipeline.java:75) >>> at >>> org.apache.camel.processor.UnitOfWorkProcessor.processNext(UnitOfWorkProcessor.java:70) >>> at >>> org.apache.camel.processor.DelegateProcessor.process(DelegateProcessor.java:48) >>> at >>> org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:67) >>> at >>> org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:84) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:543) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:482) >>> at >>> org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:451) >>> at >>> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:323) >>> at >>> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:261) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:974) >>> at >>> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:876) >>> at java.lang.Thread.run(Thread.java:619) >>> Caused by: javax.security.auth.login.LoginException: invalid username or >>> password >>> at >>> com.referentia.sdf.csproto.node.components.ClientGatewayComponent$LoginServiceImpl.login(ClientGatewayComponent.java:205) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at >>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>> at >>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>> at java.lang.reflect.Method.invoke(Method.java:597) >>> at >>> com.referentia.commons.lang.reflect.RetargettableProxy$Handler.invoke(RetargettableProxy.java:236) >>> at $Proxy12.login(Unknown Source) >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>> at >>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >>> at >>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >>> at java.lang.reflect.Method.invoke(Method.java:597) >>> at >>> org.apache.camel.component.bean.BeanInvocation.invoke(BeanInvocation.java:86) >>> ... 25 more >>> >>> >> > > -- Claus Ibsen Apache Camel Committer Author of Camel in Action: http://www.manning.com/ibsen/ Open Source Integration: http://fusesource.com Blog: http://davsclaus.blogspot.com/ Twitter: http://twitter.com/davsclaus
