Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: Synchronous jmsTemplate with topics

  1. #1
    Join Date
    Jun 2012
    Posts
    19

    Default Synchronous jmsTemplate with topics

    I am trying to get messages from a topic - using JMSTemplate.receive - no messages come back even though I see them by going to the activeMQ admin console? How would I do it if jmsTemplate is not working?

  2. #2
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,015

    Default

    I just ran a test and it worked fine for me.

    Are you using a timeout? Is the receive() active when you publish? Messages in topics are only received by active consumers by default. Consider using a message listener container and a durable subscription (or use a queue).
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  3. #3
    Join Date
    Jun 2012
    Posts
    19

    Default

    Quote Originally Posted by Gary Russell View Post
    I just ran a test and it worked fine for me.

    Are you using a timeout? Is the receive() active when you publish? Messages in topics are only received by active consumers by default. Consider using a message listener container and a durable subscription (or use a queue).
    using the MessageListener is not ideal fro my environment bec. I only want to get the messages when the user requests it - otherwise I don't need it - so that's wh I need it working synchronously.
    Do Topics work Synchronously in the Spring environment?

    Here is how I instantiate the jmsTemplate, sender & receiver in the applicationcontext.xml
    <bean id="activeMQConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFacto ry">
    <property name="brokerURL" value="tcp://localhost:61616" />
    </bean>



    <bean id="testTopic" class="org.apache.activemq.command.ActiveMQTopic">
    <constructor-arg value="testNotifications" />
    </bean>

    <bean id="jmsSender" class="com.myJmsSender">
    <property name="jmsTemplate">
    <ref bean="jmsTemplate" />
    </property>
    </bean>
    <bean id="jmsReceiver" class="com.myJmsReceiver">
    <property name="jmsTemplate">
    <ref bean="jmsTemplate" />
    </property>
    </bean>

    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
    <property name="connectionFactory">
    <ref bean="activeMQConnectionFactory" />
    </property>
    <property name="defaultDestination" ref="testTopic"></property>

    </bean>

  4. #4
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,015

    Default

    Do Topics work Synchronously in the Spring environment?
    Yes, like I said, I just tested it and it worked fine for me. I had a jmsTemplate (similar configuration to yours) with a thread blocked in its receive() method, published a message to the topic and the template.receive() returned the message.

    You can't publish the message and then call receive(); that's not how JMS topics work (regardless of Spring).
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  5. #5
    Join Date
    Jun 2012
    Posts
    19

    Default

    Heres my jmsReceiver class, do I have to run it in a separate thread when I call JMSMessageReceiver .getMessages
    public class JMSMessageReceiver {

    protected final Log logger = LogFactory.getLog(JMSMessagePublisher.class);

    private JmsTemplate jmsTemplate;

    public JmsTemplate getjmsTemplate() {
    return jmsTemplate;
    }

    public void setjmsTemplate(JmsTemplate jmsTemplate) {
    this.jmsTemplate = jmsTemplate;
    }

    public List<String> getMessages() {
    List<String> messages = new ArrayList<String>();
    Message msg = null;
    while((msg = jmsTemplate.receive()) != null){
    try {
    TextMessage textMessage = (TextMessage) msg;
    if (msg != null) {
    messages.add(textMessage.getText());
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    return messages;
    }

  6. #6
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,015

    Default

    Please use [ code ] ... [ / code] tags (no spaces inside the brackets) when posting code and config.

    Are you saying you get zero messages? I would expect you to get one, but there is definitely a window to lose messages this way (the consumer only lives during the receive() and, like I said, if you're not consuming during the publish you will lose messages.

    For this application, you should probably drop down to some of the lower-level JmsTemplate APIs, such as...

    Code:
    jmsTemplate.execute(new SessionCallback<Object>() {
    	public Object doInJms(Session session) throws JMSException {
    		MessageConsumer consumer = session.createConsumer(destination);
    		while (true) {
    			Message message = consumer.receive();
    			System.out.println(message);
    		}
    	}
    });
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  7. #7
    Join Date
    Jun 2012
    Posts
    19

    Default

    Quote Originally Posted by Gary Russell View Post
    Please use [ code ] ... [ / code] tags (no spaces inside the brackets) when posting code and config.

    Are you saying you get zero messages? I would expect you to get one, but there is definitely a window to lose messages this way (the consumer only lives during the receive() and, like I said, if you're not consuming during the publish you will lose messages.

    For this application, you should probably drop down to some of the lower-level JmsTemplate APIs, such as...

    Code:
    jmsTemplate.execute(new SessionCallback<Object>() {
    	public Object doInJms(Session session) throws JMSException {
    		MessageConsumer consumer = session.createConsumer(destination);
    		while (true) {
    			Message message = consumer.receive();
    			System.out.println(message);
    		}
    	}
    });



    Thanks alot for your help - I see what happens when my application gets deployed my jmsReceiver is not actually added as a topic consumer to ActiveMQ - it only gets registered in activeMQ at the first call to jmsTemplate.recieve -is there a way I can make sure it gets registered as a consumer on the application startup & not at the first time that I call receive?

  8. #8
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    You can use a durable subscription, BUT earlier you said you only wanted to receive Messages when a client asks for them. If that's not the case, registering a MessageListener container is definitely simpler.

  9. #9
    Join Date
    Jun 2012
    Posts
    19

    Default

    Quote Originally Posted by Mark Fisher View Post
    You can use a durable subscription, BUT earlier you said you only wanted to receive Messages when a client asks for them. If that's not the case, registering a MessageListener container is definitely simpler.
    I ended up calling jmsTemplate.receive when the setJmsTemplate gets called on the JMSReceiver instantiation from the applicationContext.xml- this way it establishes a connection, so when messages do come in & when the client asks for it it will receive them - is that Ok?
    On the MessageListener part how do I define a clientID on startup - when I set it to be durable?

    I have seen posts which say do not use jmsTemplate.receive - is that true? if not how else should I be receiving messages synchronously?

  10. #10
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,015

    Default

    As I said, receive() on a topic has issues, because the consumer only lives within its scope, when it returns there is no consumer; if someone publishes another message while you are processing the current one, you will miss it. Use execute() with the SessionCallback as I described above.

    A Queue has no such issues. Is there some reason you need to use a topic rather than a queue for this? Do you have a requirement for multiple consumers to get a message?

    The DefaultMessageListenerContainer has a clientId property - use setClientId().
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •