2012-11-05 28 views
6

Tôi đã tạo một thiết lập yêu cầu/trả lời đơn giản với Apache Camel và JMS. Mọi thứ hoạt động tốt - các cuộc gọi được gửi đến dịch vụ phía máy chủ và kết quả được trả lại cho máy khách. Chỉ khi có ngoại lệ ở phía máy chủ, ngoại lệ này sẽ không được trả lại cho người gọi. Ngoại lệ xuất hiện trên máy chủ và máy khách nhận được thời gian chờ. Tôi muốn nhận ngoại lệ ở phía khách hàng.Apache Camel JMS - Các ngoại lệ không được trả lại cho người gọi theo yêu cầu/trả lời

Theo như tôi hiểu các tài liệu có sẵn, những gì tôi muốn là hành vi mặc định. Tôi cũng chơi xung quanh với điều khoản onException hoặc thiết lập một tuyến đường khác cho việc chuyển giao lại nhưng tất cả những gì không giúp đỡ. Vì vậy, câu hỏi của tôi là những gì tôi đang thiếu trong thiết lập của tôi để có được trường hợp ngoại lệ trả lại cho người gọi?

Dưới đây là các chi tiết (mã đơn giản):

  • Hàng đợi JMS để giao tiếp được triển khai trong một JBoss độc lập (7.1.1.FINAL)
  • JNDI được sử dụng để tra cứu các nhà máy để tạo ra các kết nối vào hàng đợi
  • các khách hàng hiện đang là một webapplication mùa xuân đang chạy trong một Jetty
  • máy chủ hiện đang là độc lập ứng dụng Java đơn giản cấu hình với mùa xuân
  • phiên bản
  • mùa xuân 3.1.2.RELEASE
  • Apache Camel 2.10.2

DTOs/ngoại lệ trao đổi giữa client và server:

public class RequestDTO implements Serializable { 
    String payload; 
    ... 
} 

public class ResponseDTO implements Serializable { 
    String payload; 
    ... 
} 

public class RmtServiceException extends Exception implements Serializable { 
    public RmtServiceException() { 
     super("Exception in service."); 
    } 
} 

Giao diện cho dịch vụ gọi qua JMS:

public interface RmtService { 
    ResponseDTO doSomething(RequestDTO request) throws RmtServiceException; 
} 

Triển khai Dịch vụ:

@Component("rmtService") 
public class RmtServiceImpl implements RmtService { 
    public ResponseDTO doSomething(RequestDTO request) throws RmtServiceException { 
     // Return a ResponseDTO if processing is successful, 
     // otherwise throw an RmtServiceException 
    } 
} 
cấu hình

Chủ đầu tư: cấu hình

<bean id="remoteJndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
    <property name="environment"> 
     <props> 
      <prop key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop> 
      <prop key="java.naming.provider.url">remote://localhost:4447</prop> 
      <prop key="java.naming.security.principal">JNDI_USER</prop> 
      <prop key="java.naming.security.credentials">JNDI_PASSWORD</prop> 
     </props> 
    </property> 
</bean> 

<bean id="remoteJmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiTemplate" ref="remoteJndiTemplate"/> 
    <property name="jndiName" value="jms/RemoteConnectionFactory"/> 
</bean> 

<bean id="authenticatedJmsConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter"> 
    <property name="targetConnectionFactory" ref="remoteJmsConnectionFactory"/> 
    <property name="username" value="JMS_USER"/> 
    <property name="password" value="JMS_PASSWORD"/> 
</bean> 

<bean name="hq" class="org.apache.camel.component.jms.JmsComponent"> 
    <property name="connectionFactory" ref="authenticatedJmsConnectionFactory"/> 
</bean> 

<camel:camelContext id="APIContext" autoStartup="true"> 
    <camel:endpoint id="queue" uri="hq:queue:test.queue"/> 
</camel:camelContext> 

<camel:proxy 
     id="rmtServiceProxy" 
     serviceInterface="RmtService" 
     serviceUrl="hq:queue:test.queue"/> 

Server:

<bean id="remoteJndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
    <property name="environment"> 
     <props> 
      <prop key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory</prop> 
      <prop key="java.naming.provider.url">remote://localhost:4447</prop> 
      <prop key="java.naming.security.principal">JNDI_USER</prop> 
      <prop key="java.naming.security.credentials">JNDI_PASSWORD</prop> 
     </props> 
    </property> 
</bean> 

<bean id="remoteJmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiTemplate" ref="remoteJndiTemplate"/> 
    <property name="jndiName" value="jms/RemoteConnectionFactory"/> 
</bean> 

<bean id="authenticatedJmsConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter"> 
    <property name="targetConnectionFactory" ref="remoteJmsConnectionFactory"/> 
    <property name="username" value="JMS_USER"/> 
    <property name="password" value="JMS_PASSWORD"/> 
</bean> 

<bean name="hq" class="org.apache.camel.component.jms.JmsComponent"> 
    <property name="connectionFactory" ref="authenticatedJmsConnectionFactory"/> 
</bean> 

<camel:camelContext id="APIContext" autoStartup="true"> 
    <camel:endpoint id="queue" uri="hq:queue:test.queue"/> 
    <camel:route> 
     <camel:from ref="queue"/> 
     <camel:to uri="bean:rmtService"/> 
    </camel:route> 
</camel:camelContext> 

hành vi quan sát được khi có một ngoại lệ ở phía máy chủ:

Trong máy chủ ghi lại Output sau xuất hiện:

ERROR: org.apache.camel.processor.DefaultErrorHandler - Failed delivery for (MessageId: ID-XXX-49296-1352104153517-0-8 on ExchangeId: ID-XXX-49296-1352104153517-0-7). Exhausted after delivery attempt: 1 caught: org.apache.camel.RuntimeCamelException: RmtServiceException: Exception in service. 
org.apache.camel.RuntimeCamelException: RmtServiceException: Exception in service. 
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1270) 
at org.apache.camel.component.bean.BeanInvocation.invoke(BeanInvocation.java:87) 
at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:130) 
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:99) 
at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:73) 
at org.apache.camel.impl.ProcessorEndpoint.onExchange(ProcessorEndpoint.java:101) 
at org.apache.camel.impl.ProcessorEndpoint$1.process(ProcessorEndpoint.java:71) 
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61) 
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) 
at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:122) 
at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:298) 
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:117) 
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) 
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99) 
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) 
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:73) 
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) 
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99) 
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) 
at org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:91) 
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) 
at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:334) 
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:220) 
at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:45) 
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) 
at org.apache.camel.processor.interceptor.DefaultChannel.process(DefaultChannel.java:303) 
at org.apache.camel.processor.RouteContextProcessor.processNext(RouteContextProcessor.java:45) 
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) 
at org.apache.camel.processor.UnitOfWorkProcessor.processAsync(UnitOfWorkProcessor.java:150) 
at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:117) 
at org.apache.camel.processor.RouteInflightRepositoryProcessor.processNext(RouteInflightRepositoryProcessor.java:48) 
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) 
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:73) 
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:99) 
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:90) 
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:73) 
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:99) 
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:86) 
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:104) 
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:562) 
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:500) 
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:468) 
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:326) 
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:264) 
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1071) 
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1063) 
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:960) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
at java.lang.Thread.run(Thread.java:680) 
Caused by: RmtServiceException: Exception in service. 
at RmtServiceImpl.doSomething(...) 
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:83) 
... 48 more 
WARN : org.apache.camel.component.jms.EndpointMessageListener - Execution of JMS message listener failed. Caused by: [org.apache.camel.RuntimeCamelException - RmtServiceException: Exception in service.] 
... (Same stacktrace again) 

Và khách hàng nhận được một thời gian chờ:

WARN : org.apache.camel.component.jms.reply.TemporaryQueueReplyManager - Timeout occurred after 20000 millis waiting for reply message with correlationID [ID-XXX-49307-1352104250851-0-13]. Setting ExchangeTimedOutException on (MessageId: ID-XXX-49307-1352104250851-0-15 on ExchangeId: ID-XXX-49307-1352104250851-0-14) and continue routing. 
2012-11-05 10:03:11.964:WARN:oejs.ServletHandler:/app/some/action 
java.lang.reflect.UndeclaredThrowableException 
at $Proxy45.doSomething(Unknown Source) 
at ... 
Caused by: 
org.apache.camel.ExchangeTimedOutException: The OUT message was not received within: 20000 millis due reply message with correlationID: ID-XXX-49307-1352104250851-0-13 not received. Exchange[Message: BeanInvocation public abstract ResponseDTO RmtService.doSomething(RequestDTO) throws RmtServiceException with [[email protected]]]] 
at org.apache.camel.component.jms.reply.ReplyManagerSupport.processReply(ReplyManagerSupport.java:133) 
at org.apache.camel.component.jms.reply.TemporaryQueueReplyHandler.onTimeout(TemporaryQueueReplyHandler.java:61) 
at org.apache.camel.component.jms.reply.CorrelationTimeoutMap.onEviction(CorrelationTimeoutMap.java:53) 
at org.apache.camel.component.jms.reply.CorrelationTimeoutMap.onEviction(CorrelationTimeoutMap.java:30) 
at org.apache.camel.support.DefaultTimeoutMap.purge(DefaultTimeoutMap.java:203) 
at org.apache.camel.support.DefaultTimeoutMap.run(DefaultTimeoutMap.java:159) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439) 
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317) 
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150) 
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98) 
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180) 
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
at java.lang.Thread.run(Thread.java:680) 

Vì vậy, một lần nữa: Mọi thứ khác hoạt động như mong đợi, chỉ ngoại lệ không được trả lại cho người gọi. Bất kỳ trợ giúp về điều này được đánh giá cao! Cảm ơn trước.

Trả lời

7

Xem tùy chọn transferException mà bạn sẽ cần phải bật để sắp xếp lại ngoại lệ và trả về dưới dạng phản hồi. Tùy chọn được ghi lại trên trang tài liệu JMS tại: http://camel.apache.org/jms

+1

Tuyệt vời, bỏ qua tùy chọn đó. Cảm ơn! – lost

Các vấn đề liên quan