Java Apache Camel JMS-异常不会随请求/回复返回给调用方

Java Apache Camel JMS-异常不会随请求/回复返回给调用方,java,spring,jboss,jms,apache-camel,Java,Spring,Jboss,Jms,Apache Camel,我使用ApacheCamel和JMS创建了一个简单的请求/应答设置。一切正常-调用被分派到服务器端服务,结果被返回到客户端。只有在服务器端出现异常时,才会将此异常返回给调用方。服务器上出现异常,客户端收到超时。我想在客户端接收异常 据我所知,可用的文档表明,我想要的应该是默认行为。我还玩弄了OneException条款,或者设置了另一条后传路线,但所有这些都没有帮助。所以我的问题是,我在设置中将异常返回给调用方时缺少了什么 以下是详细信息(代码简化): 用于通信的JMS队列部署在独立JBoss

我使用ApacheCamel和JMS创建了一个简单的请求/应答设置。一切正常-调用被分派到服务器端服务,结果被返回到客户端。只有在服务器端出现异常时,才会将此异常返回给调用方。服务器上出现异常,客户端收到超时。我想在客户端接收异常

据我所知,可用的文档表明,我想要的应该是默认行为。我还玩弄了OneException条款,或者设置了另一条后传路线,但所有这些都没有帮助。所以我的问题是,我在设置中将异常返回给调用方时缺少了什么

以下是详细信息(代码简化):

  • 用于通信的JMS队列部署在独立JBoss中(7.1.1.FINAL)
  • JNDI用于查找工厂以创建到队列的连接
  • 客户端当前是一个运行在Jetty中的SpringWebApplication
  • 该服务器目前是一个配置了Spring的简单独立Java应用程序
  • Spring版本3.1.2.0发布
  • ApacheCamel 2.10.2
客户端和服务器之间交换的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调用的服务的接口:

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>
客户端收到一个超时:

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文档页面上:

Great,忽略了该选项。谢谢
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)