View Full Version : JMS queue message viewing without removing it from the queue
dshah
Jan 19th, 2006, 04:45 PM
Can anyone tell me how I can use "jmsTemplate" (JMS 1.1) to peek at (view only) a message without actually removing it first from the queue. In other words, I would like to get a "virtual" message and if I am unable to process the message then I want to leave it on the queue (in the same sequence).
Is there a way to do that?
Thanks.
dshah
Jan 20th, 2006, 02:02 PM
I am very surprised that no one has run into this before. There's no built-in support for browsing the queue in Spring. This is an absolute necessity for a JMS application that doesn't want to loose it's messages in case it has any sort of fatal error.
mbarlotta
Jan 24th, 2006, 09:28 AM
We have done this by setting the JMS Session to CLIENT_ACKNOWLEDGE and then getting a message from the queue. We check the message and if we can't handle it or want to leave it on the queue we do not call acknowledge before closing the session. This will leave it on the queue. (per JMS specs)
However last time I used Spring/JMS (circa version 1.1.5) it could not support this.
-Mike
dshah
Jan 24th, 2006, 10:11 AM
Hey, that's great. That's exactly what I needed. I found that jmsAccessor class in version 1.2.6 has the ability to set the session.CLIENT_ACKNOWLEDGE which is used by jmsTemplate (via extending a supporting class). I just added the following line to my application context file and it didn't complain while generating the bean so I think I am good to go. The value 2 is the int value for session.CLIENT_ACKNOWLEDGE. Happy Spring'ing!
<property name="sessionAcknowledgeMode"><value>2</value></property>
mindjoy
Jul 5th, 2006, 08:11 AM
dshah, have you ever made this work to your liking? I think it's impossible with Spring JMS support (before 2 anyway). Please confirm. Thank you.
dshah
Jul 5th, 2006, 08:21 AM
I have this working. I am using Spring Framework 1.2.8. I use transaction manager in read-only mode and once processed completely, I consume the message.
Following is XML config.
<!-- JMS Queue Connection Factory -->
<bean id="internalJmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate"> <ref bean="jndiTemplate"/> </property>
<property name="jndiName"> <value>${NPA_MSG_FACTORY}</value> </property>
</bean>
<!-- Spring JMS Queue Connection Factory -->
<bean id="jmsQueueConnectionFactory" class="org.springframework.jms.connection.UserCredentials ConnectionFactoryAdapter">
<property name="targetConnectionFactory"> <ref bean="internalJmsQueueConnectionFactory"/> </property>
<property name="username"> <value>${NPA_MSG_USER}</value> </property>
<property name="password"> <value>${NPA_MSG_PWD}</value> </property>
</bean>
<!-- JMS Queue Template -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory"><ref bean="jmsQueueConnectionFactory"/></property>
<property name="sessionAcknowledgeMode"><value>2</value></property>
<property name="priority"><value>4</value></property>
<property name="explicitQosEnabled"><value>true</value></property>
<property name="pubSubDomain"><value>false</value></property>
<property name="receiveTimeout"><value>5000</value></property>
</bean>
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionM anager">
<property name="connectionFactory"><ref local="jmsQueueConnectionFactory"/></property>
</bean>
<bean id="jmsOperations" class="org.springframework.transaction.interceptor.Transa ctionProxyFactoryBean">
<property name="transactionManager"><ref local="jmsTransactionManager"/></property>
<property name="target"><ref local="jmsQueueTemplate"/></property>
<property name="transactionAttributes">
<props>
<prop key="convertAndSend*">PROPAGATION_REQUIRED</prop>
<prop key="send*">PROPAGATION_REQUIRED</prop>
<prop key="receive*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="jmsSender" class="com.wachovia.ppds.utils.tools.JMSSender">
<property name="jmsTemplate"> <ref bean="jmsQueueTemplate"/> </property>
</bean>
<bean id="jmsReceiver" class="com.wachovia.ppds.utils.tools.JMSReceiver">
<property name="jmsTemplate"> <ref bean="jmsQueueTemplate"/> </property>
</bean>
Following is the transaction manager code.
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
Message msg = jmsTemplate.receive(queueName);
Following is the standard receive that consumes the message.
Message msg = jmsTemplate.receive(queueName);
That's it.
jstrachan
Jul 6th, 2006, 03:28 AM
You really should be using a queue browser; so just create a browser using a Session.
wpoitras
Jul 6th, 2006, 10:53 AM
If you still want to use JmsTemplate, you can use JmsTemplate.execute that takes a SessionCallback (there are two versions). You still will need a little bit of try/catch/finally code for allocating/freeing the browser but the amount of boilerplate code will be less.
weggyboy
Feb 28th, 2011, 04:47 AM
Hey, that's great. That's exactly what I needed. I found that jmsAccessor class in version 1.2.6 has the ability to set the session.CLIENT_ACKNOWLEDGE which is used by jmsTemplate (via extending a supporting class). I just added the following line to my application context file and it didn't complain while generating the bean so I think I am good to go. The value 2 is the int value for session.CLIENT_ACKNOWLEDGE. Happy Spring'ing!
<property name="sessionAcknowledgeMode"><value>2</value></property>
Nice! thats exactly what I was searching for! thank you!;)
Gary Russell
Feb 28th, 2011, 06:25 AM
Since you have revived this very old thread, I'd like to point out that with Spring 3.0 you can now use SpEL to access constants such as this...
<property name="sessionAcknowledgeMode"
value="#{T(javax.jms.Session).CLIENT_ACKNOWLEDGE}"/>
In Spring 2.5 we have <util:constant/> to do a similar thing.
Powered by vBulletin® Version 4.2.1 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.