我使用 Apache Camel 和 JMS 创建了一个简单的请求/回复设置。一切正常 - 调用被分派(dispatch)到服务器端服务,结果返回到客户端。只有当服务器端出现异常时,这个异常才不会返回给调用者。异常出现在服务器上,客户端收到超时。我想在客户端接收异常。
据我了解可用的文档,我想要的应该是默认行为。我还尝试使用 onException 子句或为回传设置另一条路线,但所有这些都无济于事。所以我的问题是我在设置中缺少什么来将异常返回给调用者?
详细信息如下(代码已简化):
客户端和服务器之间交换的 DTO/异常:
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.");
}
}
通过 JMS 调用的服务接口(interface):
public interface RmtService {
ResponseDTO doSomething(RequestDTO request) throws RmtServiceException;
}
服务的实现:
@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"/>
服务器配置:
<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 [RequestDTO@...]]]
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)
所以再一次:其他一切都按预期工作,只有异常没有返回给调用者。非常感谢对此的任何帮助!提前致谢。
最佳答案
查看您需要启用的选项 transferException 以序列化异常并作为响应返回。该选项记录在 JMS 文档页面上:http://camel.apache.org/jms
关于java - Apache Camel JMS - 异常没有通过请求/回复返回给调用者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13229088/
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/