I had to conduct some JMS experiment few days ago, wrote a simple command line application using Spring for that purpose. I was using Swiftmq 7.0.0 as the JMS provider. Although I took the help of Spring documentation for JMS, I still had hard time putting it all together the way I wanted. So here I am trying to put up a kick start guide to Spring JMS. For people who have just started learning JMS, I would recommend getting a good look at Sun’s documentation on JMS first.
Anyway, lets not waste time and dive into the configuration file of Spring. Here is what you need to do -
Define a JNDI template that other beans will be using for retrieving JNDI objects.
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.provider.url">smqp://localhost:4001/timeout=10000</prop>
<prop key="java.naming.factory.initial">com.swiftmq.jndi.InitialContextFactoryImpl</prop>
</props>
</property>
</bean>
Create a connection factory. I used Topic instead of Queue for my experiment.
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref ="jndiTemplate"/>
<property name="jndiName" value="TopicConnectionFactory"/>
</bean>
Create a Spring specific JMS template that will be used for sending JMS messages. Note that we are providing connection factory and a destination to the template. Destination is the message destination which is in our case named ‘testtopic’.
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="defaultDestination" ref="destination"/>
<property name="pubSubDomain" value="true"/>
<property name="deliveryPersistent" value="true"/>
<property name="deliveryMode" value="2"/>
</bean>
<bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="testtopic"/>
</bean>
I create a MsgSender class and inject jmsTemplate and destination to it. This class simply sends a number of JMS messages to the provided destination using the template.
<bean id="sender" class="myexp.spring.MsgSender">
<property name="destination" ref="destination"/>
<property name="jmsTemplate" ref="jmsTemplate"/>
</bean>
After sending the messages, we need to receive it right?
So here we are defining a Spring specific message listener container and providing a message listener to the container. For each message received, the onMessage method of the message listener will be called. In my experiment I simply printout the message in console.
<bean id="messageListener" class="myexp.spring.ExampleListener"/>
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="destination"/>
<property name="messageListener" ref="messageListener"/>
<property name="sessionAcknowledgeModeName" value="AUTO_ACKNOWLEDGE"/>
</bean>
My message sender is simple, it sends Text Messages a number of times, like this -
jmsTemplate.send(destination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
String msgText = "Message " + messageIndex;
System.out.println("Publishing - " + msgText);
Message message = session.createTextMessage(msgText);
message.setLongProperty("startTime", System.currentTimeMillis());
return message;
}
});
I an addition to a String message, I am also adding additional property into the message. The listener class must implement javax.jms.MessageListener and implement the following method -
public void onMessage(Message message) {
TextMessage msg = (TextMessage) message;
System.out.println("Reading - " + msg.getText());
}
That is pretty much it! In this simple example, we have configured Spring to send and receive JMS messages. This was a short and example driven post for configuring JMS in Spring. But to properly use it, I would recommend everyone to study the JMS documentation of Sun and Spring properly. In addition study the API docs of some of the classes such as AbstractMessageListenerContainer, JmsTemplate, MessageListener, Destination etc.
Hi
I am working on spring,Now i have integrated JMS in spring
i am using apache tomcat server,i did whatever mentioned above,but i dont know how to configure and where this
smqp://localhost:4001/timeout=10000
port no :4001 once i tried but
it was showing error like smqp class not found exception
i don’t know how to and where that class i need to configure
Please any one help me
vijay
Hi Guy’s
i integrated spring with jms and hibernate
following code’s are here
application-context.xml
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/mobicom
root
mysql
/com/mappings/UserReg.hbm.xml
/com/mappings/RecruiterReg.hbm.xml
/com/mappings/JobDetails.hbm.xml
/com/mappings/RecWithJob.hbm.xml
/com/mappings/AddCandidateWithJob.hbm.xml
hibernate.dialect=org.hibernate.dialect.MySQLDialect
<!–07/05/2009
defaultDestination
–>
JmsSender.java
package com.sample;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class JmsSender implements Controller{
private JmsTemplate jmsTemplate;
public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public void sendMessage() {
jmsTemplate.send(new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(“Hello World”);
}
});
}
public ModelAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
try{
System.out.println(“Before”);
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{“WEB-INF/applicationContext.xml”});
System.out.println(“context=”+context);
JmsSender jmsSender = (JmsSender) context.getBean(“JmsSender”);
jmsSender.sendMessage();
System.out.println(“After”);
JmsReceiver jmsReceiver = (JmsReceiver) context.getBean(“jmsReceiver”);
jmsReceiver.reciveMessage();
System.out.println(“final”);
}catch(Exception e)
{
e.printStackTrace();
}
return null;
}
}
JmsReceiver.java
package com.sample;
import javax.jms.JMSException;
import javax.jms.TextMessage;
import org.springframework.jms.core.JmsTemplate;
public class JmsReceiver {
private JmsTemplate jmsTemplate;
public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public void reciveMessage() {
try{
TextMessage msg = (TextMessage)jmsTemplate.receive();
System.out.println(“Message received: ” +msg.getText());
}catch(JMSException e){}
}
}
finally if i run this code in tomcat server
it is showing error is like this
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{“WEB-INF/applicationContext.xml”});
file not found exception ,file could not be opened,because it doesn’t exist like that
please any one help me
Hi, This is Mohan
i am searching for swiftmq 7.0.0.jar file but i won’t find any where,if you have please send me that jar file
if i run the code what you provided i am getting following Exception,if you know can you please tell me…
INFO: Destroying singletons in {org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [jndiTemplate,connectionFactory,jmsTemplate,destination,sender,messageListener,jmsContainer,jmsReceiver]; root of BeanFactory hierarchy}
Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘connectionFactory’ defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Cannot instantiate class: com.swiftmq.jndi.InitialContextFactoryImpl [Root exception is java.lang.ClassNotFoundException: com.swiftmq.jndi.InitialContextFactoryImpl]
Caused by: javax.naming.NoInitialContextException: Cannot instantiate class: com.swiftmq.jndi.InitialContextFactoryImpl [Root exception is java.lang.ClassNotFoundException: com.swiftmq.jndi.InitialContextFactoryImpl]
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:657)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:247)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.(InitialContext.java:197)
at org.springframework.jndi.JndiTemplate.createInitialContext(JndiTemplate.java:106)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:84)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:122)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:147)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:90)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:101)
at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:164)
at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:151)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1062)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1029)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:420)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:287)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:348)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:92)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:77)
at JClient.main(JClient.java:12)
Caused by: java.lang.ClassNotFoundException: com.swiftmq.jndi.InitialContextFactoryImpl
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:242)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:42)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:654)
… 23 more
Hi Mohan,
You can get the jar from http://www.swiftmq.com/
It’s a commercial software, so you have to download evaluation copy.
You are, however, free to use other JMS providers such as Apache ActiveMQ. This one is open source.
Hi Mohan,
You can go for JBOSS.