2012-11-05 12 views
6

Apache CamelとJMSを使用して簡単な要求/応答セットアップを作成しました。すべて正常に動作し、呼び出しはサーバー側のサービスに送出され、結果はクライアントに返されます。サーバー側で例外が発生した場合にのみ、この例外は呼び出し側に返されません。例外がサーバーに表示され、クライアントはタイムアウトを受信します。私はクライアント側で例外を受け取りたいと思います。Apache Camel JMS - 要求/応答で呼び出し元に例外が返されない

私が欲しいのは既定の動作でなければならないと私が利用できるドキュメントを理解している限りです。私はonException節で回ったり、バック転送のための別のルートを設定しましたが、それは役に立たなかっただけです。だから私の質問は何が私のセットアップでは、例外が呼び出し元に返されないために欠けている?ここで

は(コードが簡素化)詳細は:

  • JNDIは、接続を作成するために工場を検索するために使用される通信のためのJMSキューは、スタンドアロンのJBoss(7.1.1.FINAL)に配備されている
    • キュー
    • に、クライアントは、現在突堤で実行されている春のwebアプリケーションでサーバーが現在春
    • 春バージョンで構成されたシンプルなスタンドアロンのJavaアプリケーションです
    • public interface RmtService { 
          ResponseDTO doSomething(RequestDTO request) throws RmtServiceException; 
      } 
      

      :JMS経由で呼び出されたサービスのために

      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."); 
          } 
      } 
      

      インタフェース:3.1.2.RELEASE

    • Apacheのラクダ2.10.2

    のDTO /例外は、クライアントとサーバー間で交換しましたサービスの実装:

    @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 
        } 
    } 
    

    クライアント構成:

    <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> 
    

    観察された行動、サーバー側の例外があります:

    サーバーでは、次の出力をログに記録が表示されます。

    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) 
    

    クライアントがタイムアウトを受け取る:だからもう一度

    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) 
    

    :予想通り他のすべてが動作しますが、唯一の例外は、呼び出し側に返されません。これに関する助けがあれば大歓迎です!前もって感謝します。

  • 答えて

    7

    例外をシリアル化して応答として返すために有効にする必要のあるtransferExceptionオプションを参照してください。このオプションは、JMSドキュメントページのhttp://camel.apache.org/jms

    +1

    に記載されています。ありがとう! – lost

    関連する問題