1)Introduction
JMS API is Java Message Service API that allows components to communicate asynchronously. JMS enables two components to send and receive message without knowing each other. Spring provides support for JMS programming. Spring is a widely used framework to develop enterprise application. It is bundled with many APIs like AOP, IOC, Spring MVC,Spring JMS etc. This article can be used by beginners to write simple programs using Spring API to integrate with Weblogic JMS .Here weblogic is used because it supports many features to provide communication between sender and receiver.It acts as a middleware for JMS application.
2)Why do we need JMS?
Enterprise Application is a software to solve enterprise problem. It has many business requirements to solve the problem. To have better modularity, the requirements will be developed as different software components and programmer will integrate these components to complete entire enterprise application. The programmer needs to consider many factors while integrating the components. The following scenarios will give the clear picture about the some factors with respect to component integration
also read:
Scenario #1:
Assume that there two components called OrderProcessing and CreditCardVerification. The OrderProcessing component needs to communicate to the CreditCardVerifcation but it is not having the interface of the CreditCardVerification.
How it is going to communicate?
Scenario #2:
Assume that there are two Components called TransactionBean and HistoryBean(to record each transaction). For each transaction, the TransactionBean is going to send information to the HistoryBean and it doesn?t want to wait till the HistoryBean completes the work.
How to develop the TransactionBean to have asynchronous communication to HistoryBean?
The solution is provided by JMS.
3)Introduction to JMS API
JMS API is Java Message Service API that allows components to communicate asynchronously. JMS enables two components to send and receive message without knowing each other. Messaging provides communication between software components or applications. A messaging component can send messages to, and receive messages from, any other component. This is achieved with help of JMS Provider. The JMSProvider is a MOM (Message Oriented Middleware); sitting between sender and receiver components for asynchronous communication i.e. if a sender sends a message, the same will be stored inside MOM. The MOM then forwards the message to receiver.
To achieve the communication, following components will be configured inside the MOM.
- Connectionfactoires:Provides the communication to client programs
- Destination: Stores the messages.There are two types.
- Queue:Message will be delivered to Only one receiver
- Topic-Message will be delivered to more than one receiver
4) Weblogic JMS Provider
One of the widely used providers is Web logic. It is widely used because of following features.
- Provides messaging API.
- Supports clustering.
- Platform independent.
- Resources can be configured using Web Logic Administration Console.
- Supports XML message.
- Supports multicasting delivery.
5) Spring JMS API
Spring supports JMS framework that simplifies the complexity of the JMS implementation. The package org.springframework.jms.core provides the API for JMS core functionality. A JMS Programmer can write JMS application using Spring IOC and Spring JMS API easily. Using Spring JMS and Dependency injection, the JMS configuration details are migrated from Java code to xml file
The Spring JMS API supports a template mechanism to hide the details of Java APIs. Programmers can use JDBC Template and JNDI Template classes to use Web logic JMS resource. Spring supports the JMS Template, so developers don’t have to write the complex code for JMS implementation. Templates are helper classes used to reduce the complexity of JMS and handle the creation and release of JMS resources like connection factories, destinations, and sender/receiver objects.
We attempt to provide you, in this article, a step by step solution for Integrating Spring, JMS and Web logic. It is addressed to the audience who are aware of the basics of Spring IOC, Web logic and JMS. The article also provides the detailed information about the JMS implementation using Spring JMS. This article will help the programmer to write JMS application using Spring. Programmers can use the configuration file as basic setup for JMS application in addition they can develop application as well.
6) Steps to integrate Spring JMS and Weblogic
Step 1:
- Configure the following JMS resource inside the web logic server.
- ConnectionFactory- jms/connectionFactory and
Queue Destination- jms/testQueue
Step 2:
Create dynamic web application in the Web logic workshop
Step 3:
Import Spring.jar,
Commons-logging.jar and
log4j-1.2.15.jar
Step 4:
Create the InvoiceQueueSender class in the package jms. The class InvoiceQueueSender is used to send messages. The JMSTemplate is injected into InvoiceQueueSender using IOC container. JMS Template is used for sending and receiving messages using Message Creator. The Message Creator is a call back interface which has createMessage to create messages. JMS Template has send method which takes the parameter, Queue name and message creator.
Sample Code
package jms; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.Session; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.core.MessageCreator; public class InvoiceQueueSender { private JmsTemplate jmsTemplate; public void setJmsTemplate(JmsTemplate jmsTemplate) { this.jmsTemplate = jmsTemplate; } public void sendMesage() { MessageCreator messageCreator=new MessageCreator() { public Message createMessage(Session session) throws JMSException { return session.createTextMessage("I am sending Invoice message");} }; jmsTemplate.send("jms/testQueue", messageCreator); } }
Step 5:
Create the InvoiceMDB class in the package jms. It is a MessageDrivenBean. The InvoiceMDB is a MDB and it implements MessageListener interface. The onMessage will be executed automatically whenever message is delivered to the Queue or Topic.
Sample Code
package jms; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; public class InvoiceMDB implements MessageListener { public void onMessage(Message message) { try { System.out.println(((TextMessage) message).getText()); System.out.println("Hello"); } catch (JMSException ex) { throw new RuntimeException(ex); } } }
Step 6:
The following details will be configured inside spring configuration file. Here the file name is applicationContext.xml.
JNDITemplate
It helps us to perform JNDI operations. It has methods to do lookup and binding operation. The web logic context details are configured using this interface.
<bean id="jndiTemplate" class="org.springframework .jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial"> weblogic.jndi.WLInitialContextFactory</prop> <prop key="java.naming.provider.url">t3://localhost:7001</prop> </props> </property> </bean>
JndiObjectFactoryBean
It is used to look up the JNDI object on startup and cache it. This interface is used to configure connection factory.
<bean id="queueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate" /> </property> <property name="jndiName"> <value>jms/connectionFactory</value> </property> </bean>
DestinationResolver
It is used by JmsTemplate to resolve destination names
<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>
JMSTemplate
It is used to send messages. This requires information about connection factory and destination resolver while configuring.
<bean id="invoiceQueueTemplate" class="org.springframework.jms .core.JmsTemplate"> <property name="connectionFactory"> <ref bean="queueConnectionFactory" /> </property> <property name="destinationResolver"> <ref bean="jmsDestinationResolver" /> </property> </bean>
Queue
The destination details will be configured using JndiObjectFactoryBean
<bean id="invoiceQueue" class="org.springframework .jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate" /> </property> <property name="jndiName"> <value>jms/testQueue</value> </property> </bean>
MDB(MessageDrivenBean)
The details about Message driven will configured as a normal bean
<bean id="invoiceListener" class="jms.InvoiceMDB" />
Listener Configuarion
This class is used to configure the normal bean as message driven bean. While configuring, the destination details will be supplied so that the framework can have the relationship between MDB and destination
<bean id="Invoicelistener" class="org.springframework.jms .listener.DefaultMessageListenerContainer"> <property name="concurrentConsumers" value="5" /> <property name="connectionFactory" ref="queueConnectionFactory" /> <property name="destination" ref="invoiceQueue" /> <property name="messageListener" ref="invoiceListener" /> </bean>
SenderBean
<bean id="jmsInvoiceSender" class="jms.InvoiceQueueSender"> <property name="jmsTemplate"> <ref bean="invoiceQueueTemplate" />
The final contents will be
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="invoiceListener" class="jms.InvoiceMDB" /> <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial">weblogic.jndi .WLInitialContextFactory</prop> <prop key="java.naming.provider.url">t3://localhost:7001</prop> </props> </property> </bean> <bean id="queueConnectionFactory" class="org.springframework. jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate" /> </property> <property name="jndiName"> <value>jms/connectionFactory</value> </property> </bean> <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> <bean id="invoiceQueueTemplate" class="org.springframework .jms.core.JmsTemplate"> <property name="connectionFactory"> <ref bean="queueConnectionFactory" /> </property> <property name="destinationResolver"> <ref bean="jmsDestinationResolver" /> </property> </bean> <bean id="jmsInvoiceSender" class="jms.InvoiceQueueSender"> <property name="jmsTemplate"> <ref bean="invoiceQueueTemplate" /> </property> </bean> <bean id="invoiceQueue" class="org.springframework.jndi .JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate" /> </property> <property name="jndiName"> <value>jms/testQueue</value> </property> </bean> <bean id="Invoicelistener" class="org.springframework.jms .listener.DefaultMessageListenerContainer"> <property name="concurrentConsumers" value="5" /> <property name="connectionFactory" ref="queueConnectionFactory" /> <property name="destination" ref="invoiceQueue" /> <property name="messageListener" ref="invoiceListener" /> </bean> </beans>
Step 7:
Create Servlet to send message
package jms; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; public class InvoiceSenderServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { WebApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(this.getServletContext()); InvoiceQueueSender sender = (InvoiceQueueSender) ctx .getBean("jmsInvoiceSender"); sender.sendMesage(); } }
Step 8:
Configure the spring configuration details in the web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name> SpringJMS</display-name> <servlet> <description> </description> <display-name> InvoiceSenderServlet</display-name> <servlet-name>InvoiceSenderServlet</servlet-name> <servlet-class> jms.InvoiceSenderServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>InvoiceSenderServlet</servlet-name> <url-pattern>/InvoiceSenderServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <listener> <listener-class>org.springframework.web.context. ContextLoaderListener</listener-class> </listener> </web-app>
Step 9:
Run the servlet and check the console.
Conclusion
Spring JMS API is used to achieve asynchronous communication. The bean configuration file plays very important role because all the resources required for JMS is configured inside xml file.The MOM is acting as a mediator between sender and receiver. Weblogic MOM supports many features for JMS.
also read:
Once the programmers start using Spring in JMS applications, they will appreciate its simplicity for asynchronous messaging. The Spring JMS framework provides a variety of Java classes to implement JMS application.
Hope this article will be useful for beginners to write JMS application using Spring and Web logic.
Acknowledgements
The Author wants to express her sincere thanks to a group of personnel from Infosys Technology who have been instrumental in bringing this article to fruition. Sangeetha S was instrumental in conducting the technical review for this article.The author sincerely thanks Raghavendran N, Rajagopalan P, Satheesha BN and SV Subrahmanya for the continued encouragement and support.
About the Author
G. Sangeetha is a Senior Technical Evangelist in Infosys Technologies, Ltd., Mysore D.C. She is a post graduate in Computer Applications from the Bharathidasan University. She has over 8 years of teaching experience in the field of Computer Technology in various organizations. She specializes in Java, J2EE and related technologies.