Announcement Announcement Module
Collapse
No announcement yet.
Sending to Multiple Message Queues Crash Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Sending to Multiple Message Queues Crash

    Hey all - this is my first project working with JMS and Spring's JMS, so as a forethought, thanks in advance for your help and baring with me

    What I'm trying to do should be simple. I have an application that needs to send three types of messages to three different queue destinations on my local WebSphere v 6.0 Server. The destinations are set up through IBM's WAS console, and I have successfully submitted messages to each queue.

    However, I can only do this once without crashing before restarting the server.

    Currently, I've followed and tweaked a pretty simple example of how to set up the JavaBeans for the ConnectionFactory and JMSTemplates. Below is the code used for that.

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans	xmlns="http://www.springframework.org/schema/beans"
    		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
    			http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
    			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd" 
    			xmlns:tx="http://www.springframework.org/schema/tx" 
    			xmlns:aop="http://www.springframework.org/schema/aop" 
    			xmlns:util="http://www.springframework.org/schema/util">
    			
    	<!-- JNDI Environment Template -->
     	<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
     		<property name="environment">
     			<props>
                            </props>
     		</property>
     	</bean>
     	
     	<!-- JMS Queue Connection Factory -->
     	<bean id="internalJmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
     		<property name="jndiTemplate">
     			<ref bean="jndiTemplate"/>
     		</property>
     		<property name="jndiName">
     			<value>jms/WCSUtils_Connection_Factory</value>
     		</property>
     	</bean>
     	<!-- Spring JMS Queue Connection Factory -->
     	<bean id="jmsQueueConnectionFactory"
            class="org.springframework.jms.connection.SingleConnectionFactory102">
            <property name="targetConnectionFactory">
                <ref bean="internalJmsQueueConnectionFactory"/>
            </property>
            <property name="pubSubDomain">
                <value>false</value>
            </property>
        </bean>
     	
     	<!-- JMS Destination Resolver -->
     	<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
     		<property name="jndiTemplate">
     			<ref bean="jndiTemplate"/>
     		</property>
     		<property name="cache">
     			<value>true</value>
     		</property>
     	</bean>
     	
    	<!-- Start JMS Queue Template -->
    	
    	<bean id="jmsTemplateAttrName" class="org.springframework.jms.core.JmsTemplate102">
    		<property name="connectionFactory">
    			<ref bean="jmsQueueConnectionFactory"/>
    		</property>
    		<property name="destinationResolver">
    			<ref bean="jmsDestinationResolver"/>
    		</property>
    		<property name="defaultDestination">
    			<ref bean="jmsTemplateLookupAttrName"/>
    		</property>
    		<property name="pubSubDomain">
    			<value>false</value>
    		</property>
    		<property name="receiveTimeout">
    			<value>20000</value>
    		</property>
    	</bean>
    	<bean id="jmsTemplateLookupAttrName" class="org.springframework.jndi.JndiObjectFactoryBean">
           	<property name="jndiName"> <value>jms/UpdateProductAttributeName</value> </property>
           	<property name="resourceRef"><value>true</value></property>  		
     	</bean>
     	
     	<bean id="jmsTemplateAttrValue" class="org.springframework.jms.core.JmsTemplate102">
    		<property name="connectionFactory">
    			<ref bean="jmsQueueConnectionFactory"/>
    		</property>
    		<property name="destinationResolver">
    			<ref bean="jmsDestinationResolver"/>
    		</property>
    		<property name="defaultDestination">
    			<ref bean="jmsTemplateLookupAttrValue"/>
    		</property>
    		<property name="pubSubDomain">
    			<value>false</value>
    		</property>
    		<property name="receiveTimeout">
    			<value>20000</value>
    		</property>
    	</bean>
    	<bean id="jmsTemplateLookupAttrValue" class="org.springframework.jndi.JndiObjectFactoryBean">
           	<property name="jndiName"> <value>jms/UpdateProductAttributeValue</value> </property>
           	<property name="resourceRef"><value>true</value></property>  		
     	</bean>
     	
     	<bean id="jmsTemplateClass" class="org.springframework.jms.core.JmsTemplate102">
    		<property name="connectionFactory">
    			<ref bean="jmsQueueConnectionFactory"/>
    		</property>
    		<property name="destinationResolver">
    			<ref bean="jmsDestinationResolver"/>
    		</property>
    		<property name="defaultDestination">
    			<ref bean="jmsTemplateLookupClass"/>
    		</property>
    		<property name="pubSubDomain">
    			<value>false</value>
    		</property>
    		<property name="receiveTimeout">
    			<value>20000</value>
    		</property>
    	</bean>
    	<bean id="jmsTemplateLookupClass" class="org.springframework.jndi.JndiObjectFactoryBean">
           	<property name="jndiName"> <value>jms/UpdateProductCategoryRelationship</value> </property>
           	<property name="resourceRef"><value>true</value></property>  		
     	</bean>
    
    	<!-- End of JMS Queue Template -->			
    
    </beans>
    Sorry if it is sloppy or difficult to understand. The jmsTemplateLookup beans are mapped to my web.xml's resources.

    To replicate the issue, I merely have to submit one message to one queue, allow it to process, and submit a new message to a different queue.

    When the message attempts to send, this happens.

    Code:
    org.springframework.jms.IllegalStateException: Connection closed; nested exception is javax.jms.IllegalStateException: Connection closed
    	at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:223)
    	at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
    	at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:430)
    	at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:474)
    	at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:466)
    	at com.qvc.salesPlanning.app.wcsutils.bo.SendRtpuDeleteManager.sendMessage(SendRtpuDeleteManager.java:199)
    	at com.qvc.salesAndService.common.util.web.SalesAndServiceAuditHandler.invoke(SalesAndServiceAuditHandler.java:127)
    	at com.qvc.salesPlanning.app.wcsutils.web.UtilsController.rtpuDeleteSubmit(UtilsController.java:1216)
    	at org.springframework.web.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:434)
    	at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:372)
    	at com.qvc.salesAndService.common.util.web.SalesAndServiceController.handleRequestInternal(SalesAndServiceController.java:63)
    	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
    	at com.qvc.salesAndService.common.util.web.SalesAndServiceAuditHandler.invoke(SalesAndServiceAuditHandler.java:127)
    	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:45)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:820)
    	at com.qvc.salesAndService.common.util.web.SalesAndServiceDispatcherServlet.access$201(SalesAndServiceDispatcherServlet.java:35)
    	at com.qvc.salesAndService.common.util.web.SalesAndServiceDispatcherServlet$RequestDispatcherImpl.dispatchRequest(SalesAndServiceDispatcherServlet.java:345)
    	at com.qvc.salesAndService.common.util.web.SalesAndServiceAuditHandler.invoke(SalesAndServiceAuditHandler.java:127)
    	at com.qvc.salesAndService.common.util.web.SalesAndServiceDispatcherServlet.doDispatch(SalesAndServiceDispatcherServlet.java:261)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:755)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396)
    	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:350)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
    Caused by: javax.jms.IllegalStateException: Connection closed
    If there is anything that anybody can suggest, or if there is any more needed information for this, I'd be greatly appreciative!

    Thanks again, I'm trying to make this as clear as possible, and I take constructive criticism very well, so please do not hold back!

    Eric

  • #2
    As a follow up - I thought it'd be useful to include the class that supports this functionality.

    Code:
    /*
     * Created on July 23, 2012
     *
     */
    package com.qvc.salesPlanning.app.wcsutils.bo;
    
    import javax.sql.DataSource;
    import java.util.ArrayList;
    import java.util.HashMap;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jms.core.JmsTemplate102;
    import org.springframework.jms.core.MessageCreator;
    import javax.jms.Message;
    import javax.jms.Session;
    import javax.jms.JMSException;
    
    /**
     * @author Eric Volpone 00917312
     *
    
     */
    public class SendRtpuDeleteManager {
    	private JdbcTemplate jdbcTemplate;
    	private JmsTemplate102 jmsTemplateAttrName;
    	private JmsTemplate102 jmsTemplateAttrValue;
    	private JmsTemplate102 jmsTemplateClass;
    
    	
    	public boolean sendMessage(JmsTemplate102 template, ArrayList messages){
    		System.out.println("Message Size = " + messages.size());
    		for(int i = 0; i < messages.size(); i++){
    			final String message = (String)messages.get(i);
    
    			template.send(new MessageCreator() {
    			    public Message createMessage(Session session) throws JMSException{
    			    	return session.createTextMessage(message);
    			      }
    			    });
    			System.out.println("Message: '" + message + "' was sent!");
    		}
    		return true;
    	}
    	
    	/**
    	 * setters for data source and JmsTemplates
    	 * @param dataSource
    	 */
    	public void setDataSource(DataSource dataSource) {
    		this.jdbcTemplate = new JdbcTemplate(dataSource);
    	}
    	public void setJmsTemplateAttrName(JmsTemplate102 jmsTemplateAttrName){
    		this.jmsTemplateAttrName = jmsTemplateAttrName;
    	}
    	public JmsTemplate102 getJmsTemplateAttrName(){
    		return this.jmsTemplateAttrName;
    	}
    	public void setJmsTemplateAttrValue(JmsTemplate102 jmsTemplateAttrValue){
    		this.jmsTemplateAttrValue = jmsTemplateAttrValue;
    	}
    	public JmsTemplate102 getJmsTemplateAttrValue(){
    		return this.jmsTemplateAttrValue;
    	}
    	public void setJmsTemplateClass(JmsTemplate102 jmsTemplateClass){
    		this.jmsTemplateClass = jmsTemplateClass;
    	}
    	public JmsTemplate102 getJmsTemplateClass(){
    		return this.jmsTemplateClass;
    	}
    }
    Here's the bean

    Code:
        <bean id="SendRtpuDeleteManager" class="com.qvc.salesPlanning.app.wcsutils.bo.SendRtpuDeleteManager">
        	<property name="dataSource" ref="dataSourceDB2Container"/>
        	<property name="jmsTemplateAttrName" ref="jmsTemplateAttrName"/>
        	<property name="jmsTemplateAttrValue" ref="jmsTemplateAttrValue"/>
        	<property name="jmsTemplateClass" ref="jmsTemplateClass"/>
        </bean>

    Comment


    • #3
      You can use CachingConnectionFactory. I think that will solve your problem.

      Comment

      Working...
      X