JMS Using Spring(JmsTemplate)
Spring provides the JMSTemplate class and this template helps us to avoid a lot of boilerplate code for a JMS implementation. The following are some of the advantages provided by Spring framework when developing JMS applications for asynchronous messaging.
- It provides a JMS abstraction API that simplifies the use of JMS to access the destinations (queues or topics) and publish messages to the specified destinations.
- Java developers don't need to think about the differences between different JMS versions
- In case if we are using spring JMS module then the developers don't need to specifically deal with JMS exceptions, as Spring provides an unchecked exception for any JMS exception that is re thrown in JMS code.
Many Java classes are available in spring framework in order to simplify the use of Spring JMS, once we start using spring in JMS applications then we will know about its simplicity for asynchronous messaging.
Spring JMS main classes available in the spring framework.
Class Name | Package | Function |
JmsException | org.springframework.jms | This is the base (abstract) class for any exceptions thrown by Spring framework whenever there is a JMS exception. |
JmsTemplate, JmsTemplate102 | org.springframework.jms.core | These are helper classes used to simplify the use of JMS by handling the creation and release of JMS resources like connection factories, destinations, and sender/receiver objects. JmsTemplate102 is a subclass of JmsTemplate that uses the JMS 1.0.2 specification. |
MessageCreator | org.springframework.jms.core | This is a callback interface used by the JmsTemplate class. It creates a JMS message for a specified session. |
MessageConverter | org.springframework.jms.support.converter | This interface acts as an abstraction to convert between Java objects and JMS messages. |
DestinationResolver | org.springframework.jms.support.destination | This is an interface used by JmsTemplate for resolving destination names. DynamicDestinationResolver and JndiDestinationResolver are the default implementations of this interface. |
System Requirements:-
- Eclipse Editor or any other.
- JDK 1.5 or higher(I am using jdk 1.7.0_03)
- Spring jars version 2.5.5.
- Other related jars.
Note: - Apache Active MQ Setup is required for the execution of this example. For doing the Active MQ Setup please follow the below link:-
Required Jars:-
activemq-all-5.4.3.jar
xbean-spring-3.7.jar
activemq-pool-5.4.3.jar
commons-pool-1.5.4.jar
spring-tx.jar
spring-beans.jar
spring-context.jar
spring-context-support.jar
spring-core.jar
spring-jms.jar
Note: - I am referring spring framework 2.5.5/dist/modules directory jars.
Steps for creating Eclipse java project for implementing spring JMS:-
- Create a java project named JMSUsingSpring
- Create a package names com.gaurav.springjms.examplein the src directory
- Create a JMSTemplateTest class inside the package named com.gaurav.springjms.example.
- Place the below available code in the JMSTemplateTest java file.
JMSTemplateTest.java
packagecom.gaurav.springjms.example;
importjavax.jms.JMSException;
importjavax.jms.Message;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
importorg.springframework.jms.core.MessageCreator;
public class JMSTemplateTest {
publicstatic void main(String args[]) throws JMSException {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
"JMSMessageListenerTest-Context.xml");
JmsTemplate jmsTemplate = (JmsTemplate) appContext
.getBean("jmsTemplate");
jmsTemplate.send("TestQueueUsingSpringJMS", new MessageCreator() {
@Override
publicMessage createMessage(Session session) throws JMSException {
TextMessage textMessage = session.createTextMessage();
textMessage.setText("A Text Message from Spring JMS template By Kumar Gaurav ");
returntextMessage;
}
});
System.out.println("Message sent successfully");
Message message = jmsTemplate.receive("TestQueueUsingSpringJMS");
if(message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
String text = textMessage.getText();
System.out.println("Received :" + text);
} else {
System.out.println("Received : " + message);
}
System.out.println("Message received successfully");
System.exit(1);
}
}
- Create an XML file names JMSMessageListenerTest-Context.xml in the classpath.
- Place the below code in this file
JMSMessageListenerTest-Context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jms="http://www.springframework.org/schema/jms"xmlns:amq="http://activemq.apache.org/schema/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jms
http://www.springframework.org/schema/jms/spring-jms.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- the pooled ActiveMQ connection factory -->
<bean id="connectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<constructor-arg value="failover:(tcp://localhost:61616)" />
</bean>
<!-- configuring Spring JmsTemplate for sending messages -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="connectionFactory" />
<property name="sessionTransacted"value="false" />
<property name="receiveTimeout"value="5000" />
</bean>
</beans>
Note:-
- Local resource transactions can simply be activated through the sessionTransacted flag on the listener container definition.
- The property receiveTimeoutspecifies how long the receiver should wait before giving up waiting for a message.
- Default settings for JMS Sessions are "not transacted" and "auto-acknowledge". As defined by the J2EE specification, the transaction and acknowledgement parameters are ignored when a JMS Session is created inside an active transaction, no matter if a JTA transaction or a Spring-managed transaction. To configure them for native JMS usage, specify appropriate values for the "sessionTransacted" and "sessionAcknowledgeMode" bean properties.
- The Failover configuration syntax allows you to specify any number of composite uris. The Failover transport randomly chooses one of the composite URI and attempts to establish a connection to it. If it does not succeed or if it subsequently fails, a new connection is established to one of the other uris in the list.
Configuration Syntax
failover:(uri1,...,uriN)?transportOptions
or
failover:uri1,...,uriN
or
failover:uri1,...,uriN
- The failover transport uses random by default which lets us to load balance clients over a number of brokers.
- If we would rather connect to a primary first and only connect to a secondary backup broker if the primary is unavailable, turn off randomizing using something like
- failover:(tcp://primary:61616,tcp://secondary:61616)?randomize=false
Example:-
failover:(tcp://localhost:61616,tcp://remotehost:61616)
?initialReconnectDelay=100
Here initialReconnectDelay is the transport option which means that
How long to wait before the first reconnect attempt (in ms)
- More idea on failover please go through the below link:-
- Execute the JMSTemplateTest.java by selecting the option Run as Java Application. After Successful execution of this java file, the eclipse console will appear like below
- After Execution of this java file, we can see the status of ActiveMQ queue which is available as below:-