Announcement Announcement Module
Collapse
No announcement yet.
Are there any Spring MDP examples? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Are there any Spring MDP examples?

    Where would I look to find MDP examples using DefaultMessageListenerContainer and preferably consuming from an ActiveMQ queue?

    I'd rather just start with an example.

  • #2
    let me google that for you...

    Comment


    • #3
      Fair enough but I was wondering if there were any the the Spring folks have made available but whatever google shows will be better than nothing I guess. Just looking for a zip that will demonstrate Spring JMS with ActiveMQ.

      Comment


      • #4
        I think that's right. The google results are simply good for nothing. There are no good samples that demonstarate how to create an MDP. For example using the tutorials on net I created the following MDP, but I am only able to send but not receive my messgages. Would appreciate if someone could let me know what is wrong here:

        JMSSender.java
        Code:
        public interface JMSSender {
        	public void sendInfo();
        }
        JMSSenderImpl.java
        Code:
        import javax.jms.Destination;
        import javax.jms.JMSException;
        import javax.jms.MapMessage;
        import javax.jms.Message;
        import javax.jms.Session;
        
        import org.springframework.jms.core.JmsTemplate;
        import org.springframework.jms.core.MessageCreator;
        
        public class JMSSenderImpl implements JMSSender {
        	private JmsTemplate jmsTemplate;
        	private Destination destination;
        
        	public JMSSenderImpl() {}
        
        	public void sendInfo() {
        		jmsTemplate.send(
        				destination,
        				new MessageCreator() {
        					public Message createMessage(Session session) throws JMSException {
        						MapMessage message = session.createMapMessage();
        						
        						message.setString("name", "somename");
        						return message;
        					}
        				}
        		);
        	}
        
        	public void setJmsTemplate(JmsTemplate jmsTemplate) {
        		this.jmsTemplate = jmsTemplate;
        	}
        
        	public void setDestination(Destination destination) {
        		this.destination = destination;
        	}
        }
        JMSReceiver.java
        Code:
        import javax.jms.JMSException;
        import javax.jms.MapMessage;
        
        public class JMSReceiver {
        	public JMSReceiver() {}
        	
        	public void processMessages(MapMessage message) {
        		try {
        			System.out.println("Inside receiver");
        			String name = message.getString("name");
        			System.out.println("Received Message:" + name);
        		}
        		catch(JMSException e) {
        			e.printStackTrace();
        		}
        	}
        }
        Spring config file- message.xml
        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">
        
        		<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        			<property name="brokerURL">
        				<value>tcp://localhost:61616</value>
        			</property>
        		</bean>
        
        		<bean id="testq" class="org.apache.activemq.command.ActiveMQQueue">
        			<constructor-arg index="0" value="testq" />
        		</bean>
        		
        		<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        			<property name="connectionFactory" ref="connectionFactory"/>
        		</bean>
        		
        		<bean id="asynMessaging" class="JMSSenderImpl">
        			<property name="jmsTemplate" ref="jmsTemplate" />
        			<property name="destination" ref="testq" />
        		</bean>
        		
        		<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        			<property name="connectionFactory" ref="connectionFactory" />
        			<property name="destination" ref="testq" />
        			<property name="messageListener" ref="purePojoMdp" />
        		</bean>
        		
        		<bean id="receiver" class="JMSReceiver" />
        		
        		<bean id="purePojoMdp" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
        			<property name="delegate" ref="receiver" />
        			<property name="defaultListenerMethod" value="processMessages" />
        		</bean>
        </beans>
        Main file: Client.java
        Code:
        import org.springframework.beans.factory.BeanFactory;
        import org.springframework.beans.factory.xml.XmlBeanFactory;
        import org.springframework.core.io.ClassPathResource;
        import org.springframework.core.io.Resource;
        
        public class Client {
        	public static void main(String[] args) {
        		Resource res = new ClassPathResource("message.xml");
        		BeanFactory factory = new XmlBeanFactory(res);
        		JMSSender bean1 = (JMSSender) factory.getBean("asynMessaging");
        		System.out.println("Sending Message");
        		bean1.sendInfo();
        		System.out.println("Message Sent");
        		
        	}
        }
        The steps above are as guided in the tutorials, but I have no clue why teh queue listener is not getting invoked. Please let me know your suggestions on how to execute the client.

        P.S: I am using the eclipse IDE.

        Thanks in advance
        Last edited by pa7751; Sep 19th, 2009, 10:14 AM.

        Comment


        • #5
          I myself am just getting started but do you have to tell DMLC how many consumers you want or does it default to a value? I notice in your configuration you don't say how many you want. But it would be easy to see what the problem is if you just debug the DMLC in your IDE and see what's it's doing. You want to see that it creates the receivers for you sessions and if it does that then you should expect it to be picking messages off the queue.

          Comment


          • #6
            The default values are 1 for each of maxConcurrentConsumers and concurrentConsumers. But I tried to specify values > 1, and still I have teh same problem. the problem is that my listener code(JMSReceiver) is just not getting executed. I am missing something really. I doubt if it is right but I am actually trying to execute my Sender.java. Can you suggest if we run the MDP as a standalone java app or do we need to do anything else?
            Last edited by pa7751; Sep 19th, 2009, 12:23 PM.

            Comment


            • #7
              As I am still unfamiliar with the specifics I'd encourage you to debug the code. Look at the instance of the DMLC that's created and verify that it has created it's sessions and receivers. I still haven't worked thru a DMLC example myself yet so it's hard for me to offer any more specifics.

              Comment


              • #8
                Originally posted by pa7751 View Post
                The steps above are as guided in the tutorials, but I have no clue why teh queue listener is not getting invoked. Please let me know your suggestions on how to execute the client.

                P.S: I am using the eclipse IDE.

                Thanks in advance
                Your main class sends the message and shuts down. You may not be giving the MLC time to process the message.

                Comment


                • #9
                  Surely if the DMLC uses sync consumers it will start it's own run loop.

                  Comment


                  • #10
                    As suggested I have introduced a delay of 10 sec in my receiver class as shown below. But I still can only send messages not receive

                    Code:
                    public class JMSReceiver {
                    	public JMSReceiver() {}
                    	
                    	public void processMessages(MapMessage message) {
                    		try {
                    			System.out.println("Inside receiver");
                    			long current = System.currentTimeMillis();
                    			long future = current + 10000;// 1000 milliseconds in a second
                    			while (System.currentTimeMillis() < future) {}
                    			String name = message.getString("name");
                    			System.out.println("Received Message:" + name);
                    		}
                    		catch(JMSException e) {
                    			e.printStackTrace();
                    		}
                    	}
                    }
                    I have checked in debug mode as well. It is just not going inside my listener class. I am surely missing certain step.
                    Last edited by pa7751; Sep 19th, 2009, 02:49 PM.

                    Comment


                    • #11
                      Can you attach a zip file and I'll take a look at it for you later today.

                      I'll want to be able to reproduce the project in my IDE so please tell me what your classpath looks like.

                      Originally posted by pa7751 View Post
                      I think that's right. The google results are simply good for nothing. There are no good samples that demonstarate how to create an MDP. For example using the tutorials on net I created the following MDP, but I am only able to send but not receive my messgages. Would appreciate if someone could let me know what is wrong here:

                      JMSSender.java
                      Code:
                      public interface JMSSender {
                      	public void sendInfo();
                      }
                      JMSSenderImpl.java
                      Code:
                      import javax.jms.Destination;
                      import javax.jms.JMSException;
                      import javax.jms.MapMessage;
                      import javax.jms.Message;
                      import javax.jms.Session;
                      
                      import org.springframework.jms.core.JmsTemplate;
                      import org.springframework.jms.core.MessageCreator;
                      
                      public class JMSSenderImpl implements JMSSender {
                      	private JmsTemplate jmsTemplate;
                      	private Destination destination;
                      
                      	public JMSSenderImpl() {}
                      
                      	public void sendInfo() {
                      		jmsTemplate.send(
                      				destination,
                      				new MessageCreator() {
                      					public Message createMessage(Session session) throws JMSException {
                      						MapMessage message = session.createMapMessage();
                      						
                      						message.setString("name", "somename");
                      						return message;
                      					}
                      				}
                      		);
                      	}
                      
                      	public void setJmsTemplate(JmsTemplate jmsTemplate) {
                      		this.jmsTemplate = jmsTemplate;
                      	}
                      
                      	public void setDestination(Destination destination) {
                      		this.destination = destination;
                      	}
                      }
                      JMSReceiver.java
                      Code:
                      import javax.jms.JMSException;
                      import javax.jms.MapMessage;
                      
                      public class JMSReceiver {
                      	public JMSReceiver() {}
                      	
                      	public void processMessages(MapMessage message) {
                      		try {
                      			System.out.println("Inside receiver");
                      			String name = message.getString("name");
                      			System.out.println("Received Message:" + name);
                      		}
                      		catch(JMSException e) {
                      			e.printStackTrace();
                      		}
                      	}
                      }
                      Spring config file- message.xml
                      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">
                      
                      		<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
                      			<property name="brokerURL">
                      				<value>tcp://localhost:61616</value>
                      			</property>
                      		</bean>
                      
                      		<bean id="testq" class="org.apache.activemq.command.ActiveMQQueue">
                      			<constructor-arg index="0" value="testq" />
                      		</bean>
                      		
                      		<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
                      			<property name="connectionFactory" ref="connectionFactory"/>
                      		</bean>
                      		
                      		<bean id="asynMessaging" class="JMSSenderImpl">
                      			<property name="jmsTemplate" ref="jmsTemplate" />
                      			<property name="destination" ref="testq" />
                      		</bean>
                      		
                      		<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
                      			<property name="connectionFactory" ref="connectionFactory" />
                      			<property name="destination" ref="testq" />
                      			<property name="messageListener" ref="purePojoMdp" />
                      		</bean>
                      		
                      		<bean id="receiver" class="JMSReceiver" />
                      		
                      		<bean id="purePojoMdp" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
                      			<property name="delegate" ref="receiver" />
                      			<property name="defaultListenerMethod" value="processMessages" />
                      		</bean>
                      </beans>
                      Main file: Client.java
                      Code:
                      import org.springframework.beans.factory.BeanFactory;
                      import org.springframework.beans.factory.xml.XmlBeanFactory;
                      import org.springframework.core.io.ClassPathResource;
                      import org.springframework.core.io.Resource;
                      
                      public class Client {
                      	public static void main(String[] args) {
                      		Resource res = new ClassPathResource("message.xml");
                      		BeanFactory factory = new XmlBeanFactory(res);
                      		JMSSender bean1 = (JMSSender) factory.getBean("asynMessaging");
                      		System.out.println("Sending Message");
                      		bean1.sendInfo();
                      		System.out.println("Message Sent");
                      		
                      	}
                      }
                      The steps above are as guided in the tutorials, but I have no clue why teh queue listener is not getting invoked. Please let me know your suggestions on how to execute the client.

                      P.S: I am using the eclipse IDE.

                      Thanks in advance

                      Comment


                      • #12
                        Ok, after trying to run your example a few times, I found the problems....

                        First, you need to use an application context not a bean factory so the it actually instantiates your message listener container and invokes the lifecycle methods correctly.

                        So this:

                        Code:
                        Resource res = new ClassPathResource("message.xml");
                        BeanFactory factory = new XmlBeanFactory(res);
                        Should be this:

                        Code:
                        ApplicationContext factory = new ClassPathXmlApplicationContext("message.xml");
                        Then, you aren't implementing the listener correctly. Your message receiver can either implement jms MessageListener(in which case it will receive the jms Message types) or you can use the message listener adapter to deliver your messages to any POJO. However, that POJO must have compatible methods to receive the correct message types. In your case, you are sending MapMessages so your message handler needs to have a method:

                        Code:
                        public void processMessages(Map message) {...}
                        I made all these changes and added a brief delay to allow message processing after the send and it all works as it should.

                        Cheers!
                        Last edited by chudak; Sep 19th, 2009, 04:26 PM. Reason: fixed method signature to take Map interface

                        Comment


                        • #13
                          Here's a zipped up version of the project that I ran to test this. It's an eclipse project setup to use maven for all the dependencies.

                          Comment


                          • #14
                            Oh yes, I tried it and it works like a charm. Thank you thank you so much

                            Thanks a ton
                            Last edited by pa7751; Sep 19th, 2009, 03:56 PM.

                            Comment


                            • #15
                              Hi again

                              Now that my MDP is working, I noticed something that was going wrong with my DMLC. Could you please suggest what is happening here? I have configured my DMLC with the following setting :

                              <property name="concurrentConsumers" value="5" />
                              <property name="maxConcurrentConsumers" value="5" />


                              Yet, my activemq console shows that the number of threads that are being spawned, are anywhere in the range from 1 to 10 (although my setting is just for 5. Infact even if I remove the above settings, in which case it should default to 1, still it is spawning as many consumers as it wants to depending on the incoming load. Why do we need these setting if that is the case? Is there no way I can suggest to the conatiner to spawn only a fixed number of threads?

                              Thanks and Regards

                              Comment

                              Working...
                              X