Announcement Announcement Module
Collapse
No announcement yet.
Unable to Set JMSExpiration on Outbound Messages Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unable to Set JMSExpiration on Outbound Messages

    In a project on which I am currently working, I am using Spring Integration
    to send JMS messages to a ActiveMQ queue. I can successfully send messages
    to the queue, but I have as of yet been unable to set a non-zero JMSExpiration
    value on the messages. This is resulting in messages 'stacking up' in the
    queue if there is no active consumer.

    I have tried specifying 'time-to-live' as an attribute of my outbound
    JMS channel adapter:

    Code:
      <jms:outbound-channel-adapter id="msg.out"  
          connection-factory="externalConnectionFactory"  
          channel="outbound.msg" destination="outbound.msg.q" 
          time-to-live="10000"/>
    I have also tried using a JMS template:

    Code:
      <bean id="testJmsTemplate" class="org.springframework.jms.core.JmsTemplate" >
        <property name="connectionFactory" ref="externalConnectionFactory" />
        <property name="defaultDestinationName" value="outbound.msg.q" />
        <property name="explicitQosEnabled" value="true" />
        <property name="deliveryPersistent" value="false" />
        <property name="timeToLive" value="10000" />
      </bean>
      
      <jms:outbound-channel-adapter id="msg.out" 
         jms-template="testJmsTemplate" 
         channel="outbound.msg" />
    Neither approach seems to work. In both cases, outbound messages have an
    expiration value of '0'.

    I would greatly appreciate any ideas you could provide to me on how to
    address the problem and/or further debug the issue.

    Thank you.

    Technologies employed:
    Spring 3.1.1
    Spring Integration 2.1.0
    ActiveMQ 5.6.0

  • #2
    Refer to the schema documentation...

    Code:
    		<xsd:attribute name="time-to-live" type="xsd:string">
    			<xsd:annotation>
    				<xsd:documentation>
    	Specify the message time to live.
    	This setting will only take effect if 'explicit-qos-enabled' is true.
    				</xsd:documentation>
    			</xsd:annotation>
    		</xsd:attribute>
    or the JavaDocs for JmsTemplate

    Code:
    	/**
    	 * Set the time-to-live of the message when sending.
    	 * <p>Since a default value may be defined administratively,
    	 * this is only used when "isExplicitQosEnabled" equals "true".
    	 * @param timeToLive the message's lifetime (in milliseconds)
    	 * @see #isExplicitQosEnabled
    	 * @see javax.jms.Message#DEFAULT_TIME_TO_LIVE
    	 * @see javax.jms.MessageProducer#send(javax.jms.Message, int, int, long)
    	 */
    	public void setTimeToLive(long timeToLive) {
    ...

    Comment


    • #3
      Thank you, Mr. Russell. I was indeed missing the 'explicit-qos-enabled' attribute for my outbound channel adapter. Unfortunately, providing that attribute with a value of 'true' did not seem to make any difference in my results.

      Note also that my JMSTemplate above does, in fact, include the explicitQosEnabled property and it also does not seem to work.

      Comment


      • #4
        I just ran a test and it works fine for me...

        Code:
        15:35:00.696 DEBUG [task-scheduler-1][org.springframework.integration.jms.DynamicJmsTemplate] Sending created message: ActiveMQTextMessage {commandId = 0, responseRequired = false, messageId = null, originalDestination = null, originalTransactionId = null, producerId = null, destination = null, transactionId = null, expiration = 0, timestamp = 0, arrival = 0, brokerInTime = 0, brokerOutTime = 0, correlationId = null, replyTo = null, persistent = false, type = null, priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = {content-type=application/json, timestamp=1358541300686}, readOnlyProperties = false, readOnlyBody = false, droppable = false, text = "ccc"}
        15:35:00.716 DEBUG [org.springframework.jms.listener.DefaultMessageListenerContainer#0-1][org.springframework.jms.listener.DefaultMessageListenerContainer] Received message of type [class org.apache.activemq.command.ActiveMQTextMessage] from consumer [Cached JMS MessageConsumer: ActiveMQMessageConsumer { value=ID:arwen3-51792-1358541297411-3:1:1:1, started=true }] of session [Cached JMS Session: ActiveMQSession {id=ID:arwen3-51792-1358541297411-3:1:1,started=true}]
        1358541297411-3:1:3,started=true}
        15:35:00.801 DEBUG [org.springframework.jms.listener.DefaultMessageListenerContainer#0-1][org.springframework.integration.jms.ChannelPublishingJmsMessageListener] converted JMS Message [ActiveMQTextMessage {commandId = 7, responseRequired = true, messageId = ID:arwen3-51792-1358541297411-3:1:2:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:arwen3-51792-1358541297411-3:1:2:1, destination = queue://queue.demo, transactionId = null, expiration = 1358541310697, timestamp = 1358541300697, arrival = 0, brokerInTime = 1358541300704, brokerOutTime = 1358541300715, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@4d3af084, marshalledProperties = org.apache.activemq.util.ByteSequence@588491b8, dataStructure = null, redeliveryCounter = 0, size = 1034, properties = {timestamp=1358541300686, content-type=application/json}, readOnlyProperties = true, readOnlyBody = true, droppable = false, text = "ccc"}] to integration Message payload ["ccc"]
        I had the time to live set to 10 seconds and...

        1358541310697 == Fri Jan 18 15:35:10 EST 2013

        You can see the expiration on the receiving side.

        If you are relying on the expiration in the sender's log - you won't see it there because that log is written before the send (and the time to live is set on the send() method, not the message itself).

        Comment


        • #5
          Thank you again, Mr. Russell, for your quick and helpful response. I incorrectly determined that my test was failing because of two things:

          1) As you surmised, I was looking at the expiration value in the wrong place in my log.

          2) The clocks on my 'sending' system and 'receiving' system were out of sync, so the messages I was sending were being immediately expired and sent to activemq's DLQ

          I have some work to do to handle the clock synchronization issue, but your help has enabled me to move past the specific issue that is the subject of this thread.

          Comment

          Working...
          X