book
Article ID: KB0087142
calendar_today
Updated On:
Description
Resolution:
Issue Description:
============
Send a message to a JMS queue using "JMS Queue Sender" activity after setting the JMSExpirition value to "2" in this activity.
When you receive the message using "JMS Queue Receiver activity", the JMSExpirition becomes a timestamp value like "1380908894871". After receiving the message, try to send the same message to another queue using a "JMS Queue Sender" activity and map the JMSExpiration from the received message to the Queue Sender. You'll see the following exception in the JMS Queue Sender activity:
Input data invalid
at com.tibco.pe.core.TaskImpl.eval(Unknown Source)
at com.tibco.pe.core.Job.a(Unknown Source)
at com.tibco.pe.core.Job.k(Unknown Source)
at com.tibco.pe.core.JobDispatcher$JobCourier.a(Unknown Source)
at com.tibco.pe.core.JobDispatcher$JobCourier.run(Unknown Source)
caused by: org.xml.sax.SAXException: validation error: data "1380658412355" is not a valid int. A valid example is "-1, 0, 126789675, +100000". ({com.tibco.xml.validation}SIMPLE_E_INVALID_VALUE_FOR_TYPE) at /{http://www.tibco.com/namespaces/tnt/plugins/jms}ActivityInput[1]/JMSExpiration[1]
com.tibco.xml.validation.exception.ValueParseException: data "1380658412355" is not a valid int. A valid example is "-1, 0, 126789675, +100000".
=============
Cause:
====
1). Directly mapping the “JMSExpiration” value from the JMS Queue Receiver to the JMS Queue Sender causes the problem.
2). EMS has the JMSExpiration as a “long” value where it stores the expiration as a timestamp. Example. If you have set the expiration at two seconds and Timestamp is 1380908894871, then JMSExpiration would be 1380908896871.
The JMS receiver takes the header value directly from EMS and BW does not validate the header. Therefore, BW does not throw an error in the JMS Receiver when BW gets JMSExpiration as 1380908896871. In the JMS Queue Sender activity in BW, JMSExpiration is ab “int” and “1380908896871” is too long for an int. Therefore the error.
====
Detailed Explanation:
=============
This is an expected behavior. The interpretation of JMSExpiration in the Sender and the Receiver are a little bit different. The value of the JMSExpiration header is never set by the sender application. The JMSExpiration field that you set in the “Input” tab of the JMS Queue Sender activity is not actually the JMSExpiration header for the message, rather this value is actually a TTL (Time To Live, i.e. how long the message will live after it reaches the EMS server). Though in BW JMS Queue Sender, we call this field a JMS Expiration, still it is only TTL that is set to the message when the send call is executed. The value for the actual JMSExpiration header of the message is calculated and set automatically by the EMS client library by adding the TTL set in the JMS Sender with the JMSTimestamp of the message in Unix epoch format. This actual JMSExpiration header means the time when the message will be expired by the server (i.e. TimeStamp of the message + ttl set by the sender). When the sender sends a message with a TTL set (suppose 2 seconds), the underlying EMS client library converts the JMSTimestamp header of the message (when the send call was executed) to UNIX epoch time format. Then it sets the JMSExpiration header of the message by adding the TTL set in the send call with the JMSTimestamp in epoch format.
Example. Suppose, a sender application (irrespective of BW, it can be any sender using EMS client API) calls send() at 16:25:21.287 with TTL set as 2 seconds. Before sending out the message, the EMS client library will set the JMSTimestamp header of the message to 1381361121287 and the JMSExpiration to 1381361123287 (1381361121287 + 2000) and sends it to the server. If you set message trace for the queue in the EMS server, you will see the exact value of the JMSExpiration header for this message.
When the receiver receives the message, the JMSExpiration header value of the message will still be the time when the message will expire from the server (not the TTL). In BW Queue Receiver, we do not do any modification to the value of this header and display it in exactly same way it is received from the EMS server, i.e. in the epoch format. When using a standalone Java sample (shipped with the EMS), the value displayed for this header will still be the exact time when the message was supposed to expire from the server, but in a human readable format.
The bottom line is the JMSExpiration header of a message is not the same as the TTL set in the sender. In the BW Sender, we still call this JMSExpiration which is a little ambiguous. The TTL set in the BW Sender (JMSExpiration input) is an int, however the JMSExpiration header of an EMS message is actually a long value. So you cannot just map the JMSExpiration of a message received by Queue Receiver palette to the TTL for the Queue sender palette.
=============
Workaround:
========
To resolve this, you need to use the following xpath function for the JMS Queue Sender. Map the JMS Expiration in “JMS Queue Sender” with (JMSExpiration-JMSTimestamp) value of “JMS Queue Receiver”.
Issue/Introduction
"Input data invalid" exception in the JMS Queue Sender activity when the message with an expiration is propagated to it from a JMSQueueReceiver activity.