Will Glass
Will Glass

Reputation: 4850

Restart server without losing JMS connection

I have two app servers. One sends messages to the other using JMS. The sender runs on Tomcat, with ActiveMQ used inside a Spring Framework template method call. The receiver runs on Jetty.

The problem is that when I restart one of the servers-- the receiver of the messages-- after it restarts it doesn't get any more JMS messages until the other server is also restarted. I'm not sure why this is happening. Is there a way to only require a reboot of one server?

The sender XML configuration:

<bean id="producerJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory">
        <bean
            class="org.springframework.jms.connection.SingleConnectionFactory">
            <property name="targetConnectionFactory" ref="jmsFactory"/>
        </bean>
    </property>
</bean>

<bean id="simulationMessageSender" class="com.forio.simulate.activemq.SimulationMessageSenderImpl">
    <constructor-arg ref="producerJmsTemplate"/>
</bean>

<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"
    autowire="constructor">
    <constructor-arg value="com.forio.simulate.activemq"/>
</bean>

The sender java code:

public void send(final SimulationMessage simulationMessage) throws JMSException
{
    jmsTemplate.send(destination, new MessageCreator()
    {
        public Message createMessage(Session session) throws JMSException
        {
            Log.debug("Sending message: " + simulationMessage);
            ObjectMessage message = session.createObjectMessage(simulationMessage);
            message.setStringProperty("simulationMessage", "true");
            return message;
        }
    });
}

The receiver XML configuration:

<bean id="brokerContainer" class="org.apache.activemq.xbean.BrokerFactoryBean">
    <property name="config" value="classpath:activemq.xml" />
</bean>

<bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="${jms.url}" />
</bean>

<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"
    autowire="constructor">
    <constructor-arg>
        <value>com.forio.simulate.activemq</value>
    </constructor-arg>
</bean>

<bean id="messageListener"
    class="com.forio.simulate.activemq.SimulationMessageListener">
    <property name="messageConverter">
        <bean
            class="com.forio.simulate.activemq.converter.SimulationMessageConverter" />
    </property>
    <property name="simulationMessageService" ref="simulationMessageService"/>
</bean>

<bean
    class="org.springframework.jms.listener.SimpleMessageListenerContainer" init-method="start">
    <property name="connectionFactory" ref="jmsFactory" />
    <property name="destination" ref="destination" />
    <property name="concurrentConsumers" value="3" />
    <property name="messageListener" ref="messageListener" />
</bean>

<bean id="consumerJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsFactory" />
</bean>

Upvotes: 1

Views: 2824

Answers (1)

Tomasz Krzyżak
Tomasz Krzyżak

Reputation: 1097

It is because you are using SingleConnectionFactory. each time SingleConnectionFactory.createConnection() is called, it returns the same connection, even after it is closed by restarting your receiving server. Maybe CachingConnectionFactory will suite your needs as it has some recover on exception mechanism.

Upvotes: 3

Related Questions