Programming WebLogic JMS
You can delay the redelivery of messages when a temporary, external condition prevents an application from properly handling a message. This allows an application to temporarily inhibit the receipt of "poison" messages that it cannot currently handle. When a message is rolled back or recovered, the redelivery delay is the amount of time a message is put aside before an attempt is made to redeliver the message.
If JMS immediately redelivers the message, the error condition may not be resolved and the application may still not be able to handle the message. However, if an application is configured for a redelivery delay, then when it rolls back or recovers a message, the message is set aside until the redelivery delay has passed, at which point the messages are made available for redelivery.
All messages consumed and subsequently rolled back or recovered by a session receive the redelivery delay for that session at the time of rollback or recovery. Messages consumed by multiple sessions as part of a single user transaction will receive different redelivery delays as a function of the session that consumed the individual messages. Messages that are left unacknowledged or uncommitted by a client, either intentionally or as a result of a failure, are not assigned a redelivery delay.
For more information, see "Configure connection factories" in the Administration Console Online Help.
The application that creates the session can then override the connection factory setting using WebLogic-specific extensions to the
javax.jms.Session interface. The session attribute is dynamic and can be changed at any time. Changing the session redelivery delay affects all messages consumed and rolled back (or recovered) by that session after the change except when the message is in a session using non-durable topics.
Note: When a session is using non-durable topics, the
setRedeliveryDelay method does not apply. This may result in unexpected behavior if you are using a non-durable topic consumer to drive a workflow.
The method for setting the redelivery delay on a session is provided through the
weblogic.jms.extensions.WLSession interface, which is an extension to the
javax.jms.Session interface. To define a redelivery delay for a session, use the following methods:
For more information on the
WLSession class, refer to the weblogic.jms.extensions.WLSession Javadoc.
Regardless of what redelivery delay is set on the session, the destination where a message is being rolled back or recovered can override the setting. The redelivery delay override applied to the redelivery of a message is the one in effect at the time a message is rolled back or recovered.
You can specify a limit on the number of times that WebLogic JMS will attempt to redeliver a message to an application. Once WebLogic JMS fails to redeliver a message to a destination for a specific number of times, the message can be redirected to an error destination that is associated to the message destination. If the redelivery limit is configured, but no error destination is configured, then persistent or non-persistent messages are simply deleted when they reach their redelivery limit.
Alternatively, you can set the redelivery limit value dynamically using the message producer's set method, as described in Setting Message Producer Attributes.
When a destination's attempts to redeliver a message to a consumer reaches a specified redelivery limit, then the destination deems the message undeliverable. The
RedeliveryLimit attribute is set on a destination and is configurable using the Administration Console. This setting overrides the redelivery limit set on the message producer. For more information, see:
If an error destination is configured on the JMS server for undelivered messages, then when a message has been deemed undeliverable, the message will be redirected to a specified error destination. The error destination can be either a queue or a topic, and it must be configured on the same JMS server as the destination for which it is defined. If no error destination is configured, then undeliverable messages are simply deleted.
Note: BEA recommends that applications that use Ordered Redelivery upgrade to Message Unit-of-Order. See Using Message Unit-of-Order.
As per the JMS Specification, all messages initially delivered to a consumer from a given producer are guaranteed to arrive at the consumer in the order in which they were produced. WebLogic JMS goes above and beyond this requirement by providing the "Ordered Redelivery of Messages" feature, which guarantees the correct ordering of redelivered messages as well.
Note: With respect to MDBs (message-driven beans), the number of consumers is a function of the number of MDB instances deployed for a given MDB. The initial and maximum values for the number of instances must be set to 1. Otherwise no ordering guarantees can be made with respect to redelivered messages.
For asynchronous consumers or JMS applications using the WebLogic Messaging Bridge or MDBs, the size of the message pipeline must be set to 1. The pipeline size is set using the Messages Maximum attribute on the JMS connection factory used by the receiving application. Any value higher than 1 means there may be additional in-flight messages that will appear ahead of a redelivered message. MDB applications must define an application-specific JMS connection factory and set the Messages Maximum attribute value to 1 on that connection factory, and then reference the connection factory in the EJB descriptor for their MDB application.
For more information about programming EJBs, see "Designing Message-Driven EJBs" in Programming WebLogic Enterprise JavaBeans.
JMS applications that implement the Ordered Redelivery feature will incur performance degradation for asynchronous consumers using JTA transactions (specifically, MDBs and the WebLogic Messaging Bridge). This is caused by a mandatory reduction in the number of in-flight messages to exactly 1, so messages are not aggregated when they are sent to the client.
WebLogic JMS has an active message Expiration Policy feature that allows you to control how the system searches for expired messages and how it handles them when they are encountered. This feature ensures that expired messages are cleaned up immediately, either by simply discarding expired messages, discarding expired messages and logging their removal, or redirecting expired messages to an error destination configured on the local JMS server.
You can schedule message deliveries to an application for specific times in the future. Message deliveries can be deferred for short periods of time (such as seconds or minutes) or for long stretches of time (for example, hours later for batch processing). Until that delivery time, the message is essentially invisible until it is delivered, allowing you to schedule work at a particular time in the future.
Messages are not sent on a recurring basis; they are sent only once. In order to send messages on a recurring basis, a received scheduled message must be sent back to its original destination. Typically, the receive, the send, and any associated work should be under the same transaction to ensure exactly-once semantics.
Support for setting and getting a time-to-deliver on an individual producer is provided through the
weblogic.jms.extensions.WLMessageProducer interface, which is an extension to the
javax.jms.MessageProducer interface. To define a time-to-deliver on an individual producer, use the following methods:
For more information on the
WLMessageProducer class, refer to the weblogic.jms.extensions.WLMessageProducer Javadoc.
DeliveryTime is a JMS message header field that defines the earliest absolute time at which the message can be delivered. That is, the message is held by the messaging system and is not given to any consumers until that time.
Note: Setting a delivery time value on a message has no effect on this field, because JMS will always override the value with the producer's value when the message is sent or published. The message delivery time methods described here are similar to other JMS message fields that are set through the producer, including the delivery mode, priority, time-to-deliver, time-to-live, redelivery delay, and redelivery limit fields. Specifically, the setting of these fields is reserved for JMS providers, including WebLogic JMS.
The support for setting and getting the delivery time on a message is provided through the
weblogic.jms.extensions.WLMessage interface, which is an extension to the
javax.jms.Message interface. To define a delivery time on a message, use the following methods:
For more information on the
WLMessage class, refer to the weblogic.jms.extensions.WLMessage Javadoc.
When a producer is created it inherits its
TimeToDeliver attribute, expressed in milliseconds, from the connection factory used to create the connection that the producer is a part of. Regardless of what time-to-deliver is set on the producer, the destination to which a message is being sent or published can override the setting. An administrator can set the
TimeToDeliverOverride attribute on a destination in either a relative or scheduled string format.
TimeToDeliverOverride can also be specified using the weblogic.jms.extensions.Schedule class, which provides methods that take a schedule and return the next scheduled time for delivering messages.
Similar BNF statements for milliseconds, minute, hour, day-of-month, month, and day-of-week can be derived from the second syntax. The values for each field are defined as non-negative integers in the following ranges:
Using this syntax, each field can be represented as a range of values indicating all times between the two times. For example,
2-6 in the
dayOfWeek field indicates Monday through Friday, inclusive. Each field can also be specified as a comma-separated list. For instance, a minute field of
0,15,30,45 means every quarter hour on the quarter hour. Lastly, each field can be defined as both a set of individual values and ranges of values. For example, an hour field of
9-17,0 indicates between the hours of 9 A.M. and 5 P.M., and on the hour of midnight.
dayOfWeekequates to Sunday.
last(not case sensitive) indicates the greatest possible value for a field.
Note: When a Calendar is not supplied as a method parameter to one of the static methods in this class, the calendar used is a
java.util.GregorianCalendar with a default
java.util.TimeZone and a default
weblogic.jms.extensions.schedule class has methods that will return the next scheduled time that matches the recurring time expression. This expression uses the same syntax as the
TimeToDeliverOverride. The time returned in milliseconds can be relative or absolute.
For more information on the
WLSession class, refer to the weblogic.jms.extensions.Schedule Javadoc.
An exception listener asynchronously notifies an application whenever a problem occurs with a connection. This mechanism is particularly useful for a connection waiting to consume messages that might not be notified otherwise.
This method returns a
ConnectionMetaData object that enables you to access JMS metadata. The following table lists the various type of JMS metadata and the get methods that you can use to access them.
For more information about the
ConnectionMetaData class, see the javax.jms.ConnectionMetaData Javadoc.
A newly created connection is stopped—no messages are received until the connection is started. Typically, other JMS objects are set up to handle messages before the connection is started, as described in Setting Up a JMS Application. Messages may be produced on a stopped connection, but cannot be delivered to a stopped connection.
Typically, a JMS Provider allocates a significant amount of resources when it creates a connection. When a connection is no longer being used, you should close it to free up resources. A connection can be closed using the following method:
When you close a connection, all associated objects are also closed. You can continue to use the message objects created or received via the connection, except the received message's
acknowledge() method. Closing a closed connection has no effect.
An exception listener asynchronously notifies a client in the event a problem occurs with a session. This is particularly useful for a session waiting to consume messages that might not be notified otherwise.
Note: Because there can only be one thread per session, an exception listener and message listener (used for asynchronous message delivery) cannot execute simultaneously. Consequently, if a message listener is executing at the time a problem occurs, execution of the exception listener is blocked until the message listener completes its execution. For more information about message listeners, see Receiving Messages Asynchronously.
As with connections, a JMS Provider allocates a significant amount of resources when it creates a session. When a session is no longer being used, it is recommended that it be closed to free up resources. A session can be closed using the following
The JMS server removes the deleted destination in real time, therefore, it's not necessary to redeploy the JMS server for the deletion to take effect. The associated procedures for dynamically deleting destinations are described in the following sections.
InvalidDestinationException— as if the destination does not exist.
ConsumerClosedException, which is delivered to the
ExceptionListener, if any, of the parent session, and which will read "Destination was deleted".
When a consumer is closed, if it has an outstanding
receive() operation, then that operation is cancelled and the caller receives a
null indicating that no message is available. Attempts by an application to do anything but
close() a closed consumer will result in an
close()a closed browser will result in an
IllegalStateException. Closing of a browser implicitly closes all enumerations associated with the browser.
hasMoreElements()returns a value of true, and no subsequent call to
nextElement()has been made, then the enumeration guarantees that the next element can be enumerated. This produces the specifics. When the last call before the close was to
hasMoreElements(), and the value returned was true, then the following behaviors apply:
nextElement()will return a message.
nextElement()will throw a
hasMoreElements()made before the first call to
nextElement()will return true.
hasMoreElements()made after the first call to
nextElement()will return false.
If a given enumeration has never been called, or the last call before the close was to
nextElement(), or the last call before the close was to
hasMoreElements() and the value returned was false, then the following behaviors apply:
hasMoreElements()will return false.
nextElement()will throw a
ResourceAllocationException. For more information on using blocking send operations.
If a destination with persistent messages is deleted and then immediately recreated while the JMS server is not running, the JMS server will compare the version number of the destination (using the
CreationTime field in the configuration
config.xml file) and the version number of the destination in the persistent messages. In this case, the left over persistent messages for the older destination will have an older version number than the version number in the
config.xml file for the recreated destination, and when the JMS server is rebooted, the left over persistent messages are simply discarded.
However, if a persistent message somehow has a version number that is newer than the version number in the
config.xml for the recreated destination, then either the system clock was rolled back when the destination was deleted and recreated (while the JMS server was not running), or a different
config.xml is being used. In this situation, the JMS server will fail to boot. To save the persistent message, you can set the version number (the
CreationTime field) in the
config.xml to match the version number in the persistent message. Otherwise, you can change the version number in the
config.xml so that it is newer than the version number in the persistent message; this way, the JMS server can delete the message when it is rebooted.
Statistics for the deleted destination and the hosting JMS server are updated as the messages are physically deleted. However, the deletion of some messages can be delayed pending the outcome of another operation. This includes messages sent and/or received in a transaction, as well as unacknowledged non-transactional messages received by a client.
JMS applications can use the
JMSReplyTo header field to return a response to a request. The sender application may optionally set the
JMSReplyTo header field of its messages to its temporary destination name to advertise the temporary destination that it is using to other applications.
Temporary destinations exist only for the duration of the current connection, unless they are removed using the
delete() method, described in Deleting a Temporary Destination.
Because messages are never available if the server is restarted, all
PERSISTENT messages are silently made
NON_PERSISTENT. As a result, temporary destinations are not suitable for business logic that must survive a restart.
Note: Temporary destinations are enabled by default via the JMS server's
Hosting Temporary Template attribute. However, if you want to create temporary destinations with specific settings, you need to modify the default
Temporary Template values using the JMS server's
Temporary Template and
Module Containing Temporary Template attributes, as explained in "Configure general JMS server properties" in the Administration Console Online Help.
For durable subscriptions, WebLogic JMS stores a message in a persistent file or database until the message has been delivered to the subscribers or has expired, even if those subscribers are not active at the time that the message is delivered. A subscriber is considered active if the Java object that represents it exists. Durable subscriptions are supported for Pub/Sub messaging only.
Note: Durable subscriptions cannot be created for distributed topics. However, you can still create a durable subscription on distributed topic member and the other topic members will forward the messages to the member that has the durable subscription. For more information on using distributed topics, see Using Distributed Destinations.
For non-durable subscriptions, WebLogic JMS delivers messages only to applications with an active session. Messages sent to a topic while an application is not listening are never delivered to that application. In other words, non-durable subscriptions last only as long as their subscriber objects. By default, subscribers are non-durable.
Note: The JMS client ID is not necessarily equivalent to the WebLogic Server username, that is, a name used to authenticate a user in the WebLogic security realm. You can, of course, set the JMS client ID to the WebLogic Server username, if it is appropriate for your JMS application.
You must specify a unique client ID. If you use this alternative approach, you can use the default connection factory (if it is acceptable for your application) and avoid the need to modify the configuration information. However, applications with durable subscriptions must ensure that they call
setClientID() immediately after creating their topic connection.
Note: When specifying the client ID using the
setClientID() method, there is a risk that a duplicate client ID may be specified without throwing an exception. For example, if the client IDs for two separate connections are set simultaneously to the same value, a race condition may occur and the same value may be assigned to both connections. You can avoid this risk of duplication by specifying the client ID during configuration.
Note: Support for durable subscriptions is a feature unique to the Pub/Sub messaging model, so client IDs are used only with topic connections; queue connections also contain client IDs, but JMS does not use them.
You may also specify a message selector for filtering messages and a
noLocal flag (described later in this section). Message selectors are described in more detail in Filtering Messages. If you do not specify a
messageSelector, by default all messages are searched.
An application can use a JMS connection to both publish and subscribe to the same topic. Because topic messages are delivered to all subscribers, an application can receive messages it has published itself. To prevent this, a JMS application can set a
noLocal flag to
noLocal value defaults to
The durable subscription
name must be unique per client ID. For information on defining the client ID for the connection, see Defining the Client ID.
Only one session can define a subscriber for a particular durable subscription at any given time. Multiple subscribers can access the durable subscription, but not at the same time. Durable subscriptions are stored within the file or database.
TopicSubscriberis still active on the session.
Note: You can also delete durable subscriptions from the Administration Console. For information on managing durable subscriptions, see Managing Durable Subscriptions.
Note: When recreating a durable subscription, be careful to avoid creating a durable subscription with a duplicate name. For example, if you attempt to delete a durable subscription from a JMS server that is unavailable, the delete call fails. If you subsequently create a durable subscription with the same name on a different JMS server, you may experience unexpected results when the first JMS server becomes available. Because the original durable subscription has not been deleted, when the first JMS server again becomes available, there will be two durable subscriptions with duplicate names.
You can monitor and manage durable topic subscribers using either the Administration Console or through public runtime APIs. This functionality also enables you to view and browse all messages, and to manipulate most messages on durable subscribers. This includes message browsing (for sorting), message manipulation (such as move and delete), and message import and export. For more information, see "Managing JMS Messages" in Configuring and Managing WebLogic JMS.
WebLogic JMS provides a set of standard header fields that you can define to identify and route messages. In addition, property fields enable you to include application-specific header fields within a message, extending the standard set. You can use the message header and property fields to convey information between communicating processes.
The primary reason for including data in a property field rather than in the message body is to support message filtering via message selectors. Except for XML message extensions, data in the message body cannot be accessed via message selectors. For example, suppose you use a property field to assign high priority to a message. You can then design a message consumer containing a message selector that accesses this property field and selects only messages of expedited priority. For more information about selectors, see Filtering Messages.
JMS messages contain a standard set of header fields that are always transmitted with the message. They are available to message consumers that receive messages, and some fields can be set by the message producers that send messages. Once a message is received, its header field values can be modified.
When modifying (overriding) header field values, you need to take into consideration instances when message fields are overwritten by the JMS subsystem. For instance, setting the priority on a producer affects the priority of the message, but a value supplied to the
send() method overrides the setting on the producer. Similarly, values set on a destination override values set by the producer or values supplied to the
send() method. The only way to verify the value of header fields is to query the message after a
For a description of the standard messages header fields, see Message Header Fields.
Note: In addition to the set method, the weblogic.jms.extensions.JMSRuntimeHelper class provides the following methods to convert between pre-WebLogic JMS 6.0 and 6.1
set()method has no impact on the message header field when the
send()method is executed. If set, this header field value will be overridden during the
examples.jms.sender.SenderServlet example, provided with WebLogic Server in the
\samples\server\examples\src\examples\jms\sender directory, where
WL_HOME is the top-level directory of your WebLogic Platform installation, shows how to set header fields in messages that you send and how to display message header fields after they are sent.
The sending application can set properties in the message, and the receiving application can subsequently view them. The receiving application cannot change the properties without first clearing them using the following
JMSX property name prefix is reserved for JMS. The connection metadata contains a list of JMSX properties, which can be accessed as an enumerated list using the
getJMSXPropertyNames() method. For more information, see Accessing Connection Metadata.
The property field can be set to any of the following types: boolean, byte, double, float, int, long, short, or string. The following table lists the Message class set and get methods for each of the supported data types.
In addition to the set and get methods described in the previous table, you can use the
getObjectProperty() methods to use the objectified primitive values of the property type. When the objectified value is used, the property type can be determined at execution time rather than during the compilation. The valid object types are boolean, byte, double, float, int, long, short, and string.
This method returns all property field names as an enumeration. You can then retrieve the value of each property field by passing the property field name to the appropriate get method, as described in the previous table, based on the property field data type.
You must specify the queue that you wish to browse. You may also specify a message selector to filter messages that you are browsing. Message selectors are described in more detail in Filtering Messages.
examples.jms.queue.QueueBrowser example, provided with WebLogic Server in the
\samples\server\examples\src\examples\jms\queue directory, where
WL_HOME is the top-level directory of your WebLogic Platform installation, shows how to access the header fields of received messages.
The following provides an excerpt from the
displayQueue() method defined in the
QueueBrowser example. In this example, the
QueueBrowser object is used to obtain an enumeration that is subsequently used to scan the queue's messages.
When a queue browser is no longer being used, you should close it to free up resources. For more information, see Releasing Object Resources.
For more information about the
QueueBrowser class, see the javax.jms.QueueBrowser Javadoc.
In many cases, an application does not need to be notified of every message that is delivered to it. Message selectors can be used to filter unwanted messages, and subsequently improve performance by minimizing their impact on network traffic.
You specify a selector when creating a queue receiver or topic subscriber, as an argument to the
TopicSession.createSubscriber() methods, respectively. For information about creating queue receivers and topic subscribers, see Step 5: Create Message Producers and Message Consumers Using the Session and Destinations.
The following sections describe how to define a message selector using SQL statements and XML selector methods, and how to update message selectors. For more information about setting header and property fields, see Setting and Browsing Message Header and Property Fields and Setting Message Property Fields, respectively.
For more information about the message selector syntax, see the javax.jms.Message Javadoc.
JMS_BEA_SELECT is a built-in function in WebLogic JMS SQL syntax. You specify the syntax type, which must be set to
xpath (XML Path Language) and an XPath expression. The XML path language is defined in the XML Path Language (XPath) document, which is available at the XML Path Language Web site at: http://www.w3.org/TR/xpath
<name>Hand-held Power Drill</name>
<description>Compact, assorted colors.</description>
<description>Three blades sizes.</description>
<name>Socket Wrench Set</name>
<description>Set of 10.</description>
For a certain class of applications, WebLogic JMS can significantly optimize topic subscriber message selectors by indexing them. These applications typically have a large number of subscribers, each with a unique identifier (like a user name), and they need to be able to quickly send a message to a single subscriber, or to a list of subscribers. A typical example is an instant messaging application where each subscriber corresponds to a different user, and each message contains a list of one or more target users.
WebLogic JMS uses this exact message selector syntax as a hint to build internal subscriber indexes. Message selectors that do not follow the syntax, or that include additional
AND clauses, are still honored, but do not activate the optimization.
Once subscribers have registered using this message selector syntax, a message published to the topic can target specific subscribers by including one or more identifiers in the message's user properties, as illustrated in the following example:
The optimized message selector and message syntax is based on the standard JMS API; therefore, applications that use this syntax will also work on versions of WebLogic JMS that do not have optimized message selectors, as well as on non-WebLogic JMS products. However, these versions will not perform as well as versions that include this enhancement.
The message selector optimization will have no effect on applications that use the
MULTICAST_NO_ACKNOWLEDGE acknowledge mode. These applications have no need no need for the enhancement anyway, since the message selection occurs on the client side rather than the server side.
It is possible for the payload of
XMLMessage to be set using one XML representation and retrieved using a different representation. For example, it is valid for the XMLMessage body to be set using a
String representation and be retrieved using a DOM representation.
Sending XML messages using a DOM representation provides a significant performance improvement over sending messages as a
String. Use the following steps to publish an XML message using a Dom Representation: