Spring JMS& Websphere MQ:应用程序未捕获消息

时间:2014-01-03 23:01:21

标签: ibm-mq spring-jms

我有一个使用spring-jms,websphere mq,websphere应用服务器7的应用程序。 在用户交互中,我将消息放入队列A中。我有一个Listener-A(使用springframework中的DefaultMessageListenerContainer)来获取消息。该侦听器-A应该处理它并向队列A-Response发送响应。在这个过程中,我试图在另一个队列B上放置另一个消息,我为其定义了不同的Listener-B。但由于某种原因,在将消息放入队列B之后,Listener-B不会将其拾起。 当我尝试将消息手动放在队列B上时,Listener-B选择消息并对其进行处理,但是当我尝试上述场景时,它不起作用。此外,当我注释掉在侦听器A中将消息放入队列B的代码时,监听器-A处理该消息并将响应发送回队列A-Response。

非常感谢任何帮助。感谢

编辑:添加了代码

这是我的弹簧配置

    <bean id="jmsListener-Parent" abstract="true"
    class="MyJmsServiceExporter">
    <property name="messageTimeToLive" value="60000" />
</bean>

<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />

<bean id="taskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
    <property name="workManagerName" value="wm/default" />
</bean>

<bean name="jmsListenerContainer-Parent"
      abstract="true"
      class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="concurrentConsumers" value="1"/>
    <property name="transactionManager" ref="transactionManager" />  
    <property name="taskExecutor" ref="taskExecutor" />
</bean>

<bean id="FirstService-Listener" parent="jmsListener-Parent">
    <property name="serviceInterface" value="FirstService" />
    <property name="service" ref="FirstServiceImpl" />
    <property name="messageConverter" ref="MyMessageConverter" />
</bean>

<bean id="SecondService-Listener" parent="jmsListener-Parent">
    <property name="serviceInterface" value="SecondService" />
    <property name="service" ref="SecondServiceImpl" />
    <property name="messageConverter" ref="MyMessageConverter" />
</bean>

<bean name="FirstService-ListenerContainer"
      parent="jmsListenerContainer-Parent">
    <property name="destination" ref="FirstQueue-Request" />
    <property name="messageListener" ref="FirstService-Listener" />
</bean>

<bean name="SecondService-ListenerContainer"
      parent="jmsListenerContainer-Parent">
    <property name="destination" ref="SecondQueue-Request" />
    <property name="messageListener" ref="SecondService-Listener" />
</bean>

<bean id="FirstService-Client"
      class="MyJmsServiceInvoker">
    <property name="connectionFactory" ref="connectionFactory" />          
    <property name="serviceInterface" value="FirstService" />
    <property name="messageConverter" ref="MyMessageConverter" />
    <property name="queue" ref="FirstQueue-Request" />
    <property name="responseQueue" ref="FirstQueue-Response" />
    <property name="timeToLive" value="60000" />
    <property name="receiveTimeout" value="60000" />            
</bean>  

<bean id="SecondService-Client"
      class="MyJmsServiceInvoker">
    <property name="connectionFactory" ref="connectionFactory" />          
    <property name="serviceInterface" value="SecondService" />
    <property name="messageConverter" ref="MyMessageConverter" />
    <property name="queue" ref="SecondQueue-Request" />
    <property name="responseQueue" ref="SecondQueue-Response" />
    <property name="timeToLive" value="60000" />
    <property name="receiveTimeout" value="60000" />            
</bean> 

MyJmsServiceInvoker(扩展JmsInvokerProxyFactoryBean)方法:

protected Message doExecuteRequest(
        Session session,
        Queue queue,
        Message requestMessage) 
throws JMSException {
    MessageProducer producer = null;
    MessageConsumer consumer = null;
    Message responseMessage = null;
    String correlationId = null;
    String responseSelector = null;

    try {
        LOG.info("CmsJmsServiceInvoker::doExecuteRequest");
        requestMessage.setJMSType("TEXT");
        requestMessage.setJMSReplyTo(responseQueue);
        requestMessage.setJMSExpiration(this.getTimeToLive());

        producer = session.createProducer(queue);

        if (isPersistentMessage()) {
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        } else {
            producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        }

        producer.setTimeToLive(getTimeToLive());

        LOG.info("Sending requestMessage.");
        producer.send(requestMessage);

        correlationId = requestMessage.getJMSMessageID();
        responseSelector = 
            "JMSCorrelationID=\'" + correlationId + "\'";

        consumer = session.createConsumer(responseQueue, responseSelector);

        long timeout = getReceiveTimeout();

        LOG.info("Awaiting response.");
        if (timeout > 0) {
            responseMessage = consumer.receive(timeout);
        } else {
            responseMessage = consumer.receive();
        }

        if (responseMessage == null) {
            LOG.info("Timeout encountered.");
            throw new RuntimeException("Timeout");
        }
    } catch (JMSSecurityException jse) {
        LOG.error("SecurityException encountered.", jse);
        throw new RuntimeException("JMS SecurityException, jse");

    } finally {
        JmsUtils.closeMessageConsumer(consumer);
        JmsUtils.closeMessageProducer(producer);
    }

    LOG.info("Returning response Message.");
    return responseMessage;      
}

MyJmsServiceExporter(扩展JmsInvokerServiceExporter)方法:

protected void writeRemoteInvocationResult(Message requestMessage,
                                           Session session,
                                           RemoteInvocationResult result)
throws JMSException {
    MessageProducer producer = null;
    Message response = null;
    if (requestMessage.getJMSReplyTo() == null) {
        LOG.debug("Async:  This request will not have a "
                  + "response since there is no reply queue in the "
                  + "JMS header.");
        return;
    }

    producer = session.createProducer(requestMessage.getJMSReplyTo());

    try {
        response = createResponseMessage(requestMessage, session,
                result);
        producer.setTimeToLive(getMessageTimeToLive());
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

        if (persistentMessage) {
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        }
        producer.send(response);

        if (LOG.isDebugEnabled()) {
            LOG.debug("Sending response message.");
            LOG.debug(response);
        }
    } finally {
        if (producer != null) {
            JmsUtils.closeMessageProducer(producer);
        }
    }
}

protected Message createResponseMessage(
        Message request,
        Session session,
        RemoteInvocationResult result) 
throws JMSException {
    Message response = null;
    String correlation = null;

    correlation = request.getJMSCorrelationID();

    response = super.createResponseMessage(request, session, result);
    if (correlation == null) {
        correlation = request.getJMSMessageID();
    }

    response.setJMSCorrelationID(correlation);
    response.setJMSExpiration(getMessageTimeToLive());

    return response;
}  


public void onMessage(Message requestMessage, Session session)
        throws JMSException {
    RemoteInvocationResult result = null;

    try {
        RemoteInvocation invocation = readRemoteInvocation(requestMessage);

        if (invocation != null) {
            result = 
                invokeAndCreateResult(invocation, getProxyForService());
        }
    } catch (Throwable throwable) {
        if (result == null) {
            result = new RemoteInvocationResult(throwable);
        }

        throwable.printStackTrace();
    } finally {
        writeRemoteInvocationResult(requestMessage, session, result);
        // JmsUtils.commitIfNecessary(session);
    }
}

FirstServiceImpl类有一个saveText方法,当将消息放入FirstQueue-Request时调用该方法。在该方法中,我试图调用SecondService方法:validateText(textmessage)。此消息放在SecondQueue-Request上,但从未读过。

1 个答案:

答案 0 :(得分:0)

发送消息后您没有提交会话。

在我看来,您正在尝试实现request-reply-by-correlationid逻辑,同时使用事务处理资源和手动会话处理;所有在同一方法(doExecuteRequest()或writeRemoteInvocationResult())。对于20行代码来说,这是很多东西。这种代码通常与临时队列一起使用..

您真的需要在会话级别编写代码吗?有没有理由不能只使用jmsTemplate发送消息,而messageListenerContainer接收回复?