【问题标题】:Setup of JMS message listener invoker failed for destination trying to recover目标尝试恢复的 JMS 消息侦听器调用程序的设置失败
【发布时间】:2014-02-20 19:36:27
【问题描述】:

在我的应用程序中运行集成测试时,我在其中一项集成测试的故障安全测试报告中收到以下错误消息:

listener.DefaultMessageListenerContainer,WARN,Setup of JMS message listener invoker failed for destination 'jms/myapp.OneWorker' - trying to recover. Cause: Destination [jms/myapp.OneWorker] not found in JNDI; nested exception is javax.naming.NameNotFoundException: jms/myapp.OneWorker

下面是我的配置细节:

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">
                org.apache.activemq.jndi.ActiveMQInitialContextFactory</prop>
            <prop key="java.naming.provider.url">vm://localhost:0</prop>
            <prop key="java.naming.security.principal">system</prop>
            <prop key="java.naming.security.credentials">system</prop>
        </props>
    </property>
</bean>

<bean id="jndiQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <property name="jndiName" value="jmsFactory" />
</bean>

<bean id="queueConnectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="jndiQueueConnectionFactory" />
    <property name="sessionCacheSize" value="1" />
</bean>

<bean id="destinationResolver"
    class="org.springframework.jms.support.destination.JndiDestinationResolver">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <property name="cache" value="true" />
    <property name="fallbackToDynamicDestination" value="false" />
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="queueConnectionFactory" />
    <property name="destinationResolver" ref="destinationResolver" />
    <property name="pubSubDomain" value="true" />
</bean>

<bean id="workerOneListener" class="com.org.myapp.workflow.WorkerOne">
    <property name="workflowManager" ref="workflowManagerImpl" />
</bean>

<jms:listener-container connection-factory="queueConnectionFactory"
    destination-resolver="destinationResolver" concurrency="3">
    <jms:listener destination="jms/myapp.OneWorker" ref="workerOneListener" />
    <jms:listener destination="jms/myapp.TwoWorker" ref="workerOneListener" />
    <jms:listener destination="jms/myapp.ThreeWorker" ref="workerOneListener" />
</jms:listener-container>  

集成测试有一个基类,它创建 Spring 应用程序上下文并由模块中的所有其他集成测试共享。
我启用了调试级别的日志记录并收到以下错误消息:

2014-01-29 11:13:24,connection.CachingConnectionFactory,DEBUG,Closing cached Session:     ActiveMQSession {id=ID:CHN03876623-56121-1390973978321-2:0:70,started=true}
2014-01-29 11:13:24,connection.CachingConnectionFactory,DEBUG,Closing cached Session: ActiveMQSession {id=ID:CHN03876623-56121-1390973978321-2:0:70,started=true}
2014-01-29 11:13:24,connection.CachingConnectionFactory,DEBUG,Creating cached JMS Session for mode 1: ActiveMQSession {id=ID:CHN03876623-56121-1390973978321-2:0:71,started=true}
2014-01-29 11:13:24,jndi.JndiTemplate,DEBUG,Looking up JNDI object with name [jms/myapp.OneWorker]
2014-01-29 11:13:24,destination.JndiDestinationResolver,DEBUG,Destination [jms/myapp.OneWorker] not found in JNDI
javax.naming.NameNotFoundException: jms/myapp.OneWorker
    at org.apache.activemq.jndi.ReadOnlyContext.lookup(ReadOnlyContext.java:225)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
    at org.springframework.jms.support.destination.JndiDestinationResolver.resolveDestinationName(JndiDestinationResolver.java:111)
    at org.springframework.jms.support.destination.JmsDestinationAccessor.resolveDestinationName(JmsDestinationAccessor.java:100)
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.createListenerConsumer(AbstractPollingMessageListenerContainer.java:221)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.initResourcesIfNecessary(DefaultMessageListenerContainer.java:1081)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)
    at java.lang.Thread.run(Thread.java:662)

此日志消息会无限重复,并且对于其他两个工作人员也是如此。并且构建在这一点上挂起。我使用unitils 框架进行集成测试,并在我的基础集成测试类中使用@SpringApplicationContext 创建spring 上下文。我哪里错了?

【问题讨论】:

    标签: spring spring-jms


    【解决方案1】:

    您正在尝试查找 JNDI 命名空间中不存在的 JMS 侦听器。您确定您正在运行 JNDI 容器并且您的 MQ 服务器正在运行和设置正确吗?

    【讨论】:

    • 相同的配置适用于我的应用程序中的其他模块。当执行此特定模块中的测试时,它会抛出所有这些错误消息。
    • 是的,库尔特,是的。正如我所说,它适用于其他模块。与其他模块的区别在于,这里的集成测试重用了基类创建的上下文。而在其他模块中,所有集成测试都在创建自己的上下文。
    【解决方案2】:

    不确定这是不是问题,但我用这种方法解决了我的问题:

    使用 @SpringApplicationContext 正在加载多个 spring xml 文件,并且最后加载的 spring xml 文件之一排除了其他上下文 xml 所需的少数类,并且重新加载了不包括这些类的上下文。

    我还看到@SpringApplicationContext的上下文文件列表中重复了几个spring xml

    我删除了冗余并重新排序或删除了不需要的 spring xmls 或其中的一些 bean。它奏效了。

    【讨论】:

      【解决方案3】:

      当我想使用相同的客户端 ID (ConnectionFactory.setClientId) 访问相同的持久订阅(即主题)时,这发生在我身上。为客户端分配唯一的客户端 ID 解决了这个问题。

      【讨论】:

      • 你是怎么处理的,你更新你的代码时需要更新你的clientId吗?
      猜你喜欢
      • 2021-07-24
      • 2016-08-30
      • 2021-08-02
      • 2023-03-18
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 2021-02-05
      • 2012-02-13
      相关资源
      最近更新 更多