6 Managing Your Applications
Learn how to manage your JMS applications programatically using the value-added WebLogic JMS features.
Managing Rolled Back, Recovered, Redelivered, or Expired Messages
Learn how to mange rolled back or recovered messages.
Setting a Redelivery Delay for Messages
You can delay the redelivery of messages when a temporary, external condition prevents an application from properly handling a message. This enables 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, then 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.
Setting a Redelivery Delay
A session inherits the redelivery delay from its connection factory when the session is created. The RedeliveryDelay
attribute of a connection factory is configured using the WebLogic Server Administration Console.
For more information, see Configure connection factories in the Oracle WebLogic Server 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:
public void setRedeliveryDelay( long redeliveryDelay ) throws JMSException; public long getRedeliveryDelay( ) throws JMSException;
For more information on the WLSession
class, refer to the weblogic.jms.extensions.WLSession
Javadoc.
Overriding the Redelivery Delay on a Destination
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.
The RedeliveryDelayOverride
attribute of a destination is configured using the WebLogic Server Administration Console. For more information, see:
-
Configure queue message delivery failure options in the Oracle WebLogic Server Administration Console Online Help
-
Configure topic message delivery failure options in the Oracle WebLogic Server Administration Console Online Help
Setting a Redelivery Limit for Messages
You can specify a limit on the number of times that WebLogic JMS will attempt to redeliver a message to an application. After 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 with the message destination. If the redelivery limit is configured, but no error destination is configured, then persistent or non-persistent messages are 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 JMSProducer and MessageProducer Attributes.
Configuring a Message Redelivery Limit on a Destination
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 WebLogic Server Administration Console. This setting overrides the redelivery limit set on the message producer. For more information, see:
-
Configure queue message delivery failure options in the Oracle WebLogic Server Administration Console Online Help.
-
Configure topic message delivery failure options in the Oracle WebLogic Server Administration Console Online Help.
Configuring an Error Destination for Undelivered Messages
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.
The ErrorDestination
attribute is configured for standalone destinations and uniform distributed destination using the WebLogic Server Administration Console. For more information, see:
-
Configure queue message delivery failure options in the Oracle WebLogic Server Administration Console Online Help.
-
Configure topic message delivery failure options in the Oracle WebLogic Server Administration Console Online Help.
-
Uniform distributed queues - configure delivery failure parameters in the Oracle WebLogic Server Administration Console Online Help.
-
Uniform distributed topics - configure delivery failure parameters in the Oracle WebLogic Server Administration Console Online Help.
Ordered Redelivery of Messages
Note:
Oracle recommends that applications use the Ordered Redelivery upgrade to Message Unit-of-Order. See Using the Message Unit-of-Order.
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.
In order to provide this guarantee, WebLogic JMS must impose certain constraints. They are:
-
Single consumers — ordered redelivery is only guaranteed when there is a single consumer. If there are multiple consumers, then there are no guarantees about the order in which any individual consumer will receive messages.
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.
-
Sort order : If a given destination is sorted, has JMS destination keys defined, and another message is produced such that the message would be placed at the top of the ordering, then no guarantee can be made between the redelivery of an existing message and the delivery of the incoming message.
-
Message selection : If a consumer is using a selector, then ordering on redelivery is only guaranteed between the message being redelivered and other messages that match the criteria for that selector. There are no guarantees of order with respect to messages that do not match the selector.
-
Redelivery delay : If a message has a redelivery delay period and is recovered or rolled back, then it is unavailable for the delay period. During that period, other messages can be delivered before the delayed message, even though these messages were sent after the delayed message.
-
Messages pending recovery : Ordered redelivery does not apply to redelivered messages that end up in a pending recovery state due to a server failure or a system reboot.
Required Message Pipeline Setting for the Messaging Bridge and MDBs
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 Message-Driven EJBs in Developing Enterprise JavaBeans, Version 2.1, for Oracle WebLogic Server.
Performance Limitations
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.
Handling Expired Messages
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.
Setting Message Delivery Times
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, enabling 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.
Setting a Delivery Time on Producers
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:
public void setTimeToDeliver( long timeToDeliver ) throws JMSException; public long getTimeToDeliver( ) throws JMSException;
For more information about the WLMessageProducer
class, see the weblogic.jms.extensions.WLMessageProducer
Javadoc.
Setting a Delivery Time on Messages
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.
As a JMS header field, DeliveryTime
can be used to sort messages in a destination or to select messages. For the purposes of data type conversion, the delivery time is stored as a long integer.
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:
public void setJMSDeliveryTime( long deliveryTime ) throws JMSException; public long getJMSDeliveryTime( ) throws JMSException;
For more information about the WLMessage
class, see weblogic.jms.extensions.WLMessage
Javadoc.
Overriding a Delivery Time
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 the time-to-deliver 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.
Interaction with the Time-to-Live Value
If the specified time-to-live value (JMSExpiration
) is less than or equal to the specified time-to-deliver value, then the message delivery succeeds. However, the message is then silently expired.
Setting a Relative Time-to-Deliver Override
The relative TimeToDeliverOverride
attribute is a string specified as an integer, and is configurable using the WebLogic Server Administration Console.
Setting a Scheduled Time-to-Deliver Override
The scheduled TimeToDeliverOverride
attribute 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.
Table 6-1 Message Delivery Schedule
Example | Description |
---|---|
0 0 0,30 * * * * |
Exact next nearest half-hour |
* * 0,30 4-5 * * * |
Anytime in the first minute of the half hours between 4 A.M. and 5 A.M. hours |
* * * 9-16 * * * |
Between 9 A.M. and 5 P.M. (9:00.00 A.M. to 4:59.59 P.M.) |
* * * * 8-14 * 2 |
The second Tuesday of the month |
* * * 13-16 * * 0 |
Between 1 P.M. and 5 P.M. on Sunday |
* * * * * 31 * |
The last day of the month |
* * * * 15 4 1 |
The next time April 15th occurs on a Sunday |
0 0 0 1 * * 2-6;0 0 0 2 * * 1,7 |
1 A.M. on weekdays; 2 A.M. on weekends |
A cron-like string is used to define the schedule. The format is defined by the following BNF syntax:
schedule := millisecond second minute hour dayOfMonth month dayOfWeek
The BNF syntax for specifying the second
field is as follows:
second := * | secondList secondList := secondItem [, secondList] secondItem := secondValue | secondRange SecondRange := secondValue - secondValue
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:
milliSecondValue := 0-999 milliSecondValue := 0-999 secondValue := 0-59 minuteValue := 0-59 hourValue := 0-23 dayOfMonthValue := 1-31 monthValue := 1-12 dayOfWeekValue := 1-7
Note:
These values equate to the same ranges that thejava.util.Calendar
class uses, except for monthValue
. The java.util.Calendar
range for monthValue
is 0-11, rather than 1-12.
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. Last, 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.
Additional semantics are as follows:
-
If multiple schedules are supplied (using a semi-colon (;) as the separator), then the next scheduled time for the set is determined using the schedule that returns the soonest value. One use for this is for specifying schedules that change based on the day of the week (see the example below).
-
A value of 1 (one) for
dayOfWeek
equates to Sunday. -
A value of * means every time for that field. For instance, a * in the Month field means every month. A * in the Hour field means every hour.
-
A value of
l
orlast
(not case sensitive) indicates the greatest possible value for a field. -
If a day of the month is specified that exceeds the normal maximum for a month, then the normal maximum for that month will be specified. For example, if it is February during a leap year and 31 was specified, then the scheduler will schedule as if 29 was specified instead. This means that setting the month field to 31 always indicates the last day of the month.
-
If milliseconds are specified, then they are rounded down to the nearest 50th of a second. The values are 0, 19, 39, 59, ..., 979, and 999. Thus, 0-40 gets rounded to 0-39 and 50-999 gets rounded to 39-999.
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 defaultjava.util.TimeZone
and a defaultjava.util.Locale
.
JMS Schedule Interface
The 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 TimeToDeliverOverride
. The time returned in milliseconds can be relative or absolute.
For more information about the WLSession
class, see weblogic.jms.extensions.Schedule
Javadoc.
You can define the next scheduled time after the given time using the following method:
public static Calendar nextScheduledTime( String schedule, Calendar calendar ) throws ParseException {
You can define the next scheduled time after the current time using the following method:
public static Calendar nextScheduledTime( String schedule, ) throws ParseException {
You can define the next scheduled time after the given time in absolute milliseconds using the following method:
public static long nextScheduledTimeInMillis( String schedule, long timeInMillis ) throws ParseException
You can define the next scheduled time after the given time in relative milliseconds using the following method:
public static long nextScheduledTimeInMillisRelative( String schedule, long timeInMillis ) throws ParseException {
You can define the next scheduled time after the current time in relative milliseconds using the following method:
public static long nextScheduledTimeInMillisRelative( String schedule ) throws ParseException {
Managing Connections
Learn how to manage JMS connections.
Defining a Connection Exception Listener
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.
Note:
The purpose of an exception listener is not to monitor all exceptions thrown by a connection, but to deliver those exceptions that would not be otherwise delivered.
You can define an exception listener for a connection using the following Connection
method:
public void setExceptionListener( ExceptionListener listener ) throws JMSException
You must specify an ExceptionListener
object for the connection.
The JMS Provider notifies an exception listener, if one has been defined, when it encounters a problem with a connection using the following ExceptionListener
method:
public void onException( JMSException exception )
The JMS provider specifies the exception that describes the problem when calling the method.
You can access the exception listener for a connection using the following Connection method:
public ExceptionListener getExceptionListener( ) throws JMSException
Accessing Connection Metadata
You can access the metadata associated with a specific connection using the following Connection
method:
public ConnectionMetaData getMetaData( ) throws JMSException
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.
Table 6-2 JMS Metadata
JMS Metadata | Get Method |
---|---|
Version |
public String getJMSVersion(
) throws JMSException |
Major version |
public int getJMSMajorVersion(
) throws JMSException |
Minor version |
public int getJMSMinorVersion(
) throws JMSException |
Provider name |
public String getJMSProviderName(
) throws JMSException |
Provider version |
public String getProviderVersion(
) throws JMSException |
Provider major version |
public int getProviderMajorVersion(
) throws JMSException |
Provider minor version |
public int getProviderMinorVersion(
) throws JMSException |
JMSX property names |
public Enumeration getJMSXPropertyNames(
) throws JMSException |
For more information about the ConnectionMetaData
class, see the javax.jms.ConnectionMetaData
Javadoc at http://docs.oracle.com/javaee/7/api/javax/jms/ConnectionMetaData.html
.
Starting, Stopping, and Closing a Connection
To control the flow of messages, you can start and stop a connection temporarily using the start()
and stop()
methods, respectively, as follows.
The start()
and stop()
method details are as follows:
public void start( ) throws JMSException public void stop( ) throws JMSException
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.
Once started, you can stop a connection using the stop()
method. This method performs the following steps:
-
Pauses the delivery of all messages. No applications waiting to receive messages will return until the connection is restarted or the time-to-live value associated with the message is reached.
-
Waits until all message listeners that are currently processing messages have completed.
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:
public void close( ) throws JMSException
This method performs the following steps to execute an orderly shutdown:
-
Terminates the receipt of all pending messages. Applications may return a message or null if a message was not available at the time of the close.
-
Waits until all message listeners that are currently processing messages have completed.
-
Rolls back in-process transactions on its transacted sessions (unless such transactions are part of an external JTA user transaction). For more information about JTA user transactions, see Using JTA User Transactions.
-
Does not force an acknowledge of client-acknowledged sessions. By not forcing an acknowledge, no messages are lost for queues and durable subscriptions that require reliable processing.
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.
Note:
Attempting to acknowledge a received message from a closed connection's session throws an IllegalStateException
.
Managing Sessions
Learn how to manage JMS sessions.
Defining a Session Exception Listener
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:
The purpose of an exception listener is not to monitor all exceptions thrown by a session, only to deliver those exceptions that would otherwise be undelivered.
You can define an exception listener for a session using the following WLSession
method:
public void setExceptionListener( ExceptionListener listener ) throws JMSException
You must specify an ExceptionListener
object for the session.
The JMS Provider notifies an exception listener, if one has been defined, when it encounters a problem with a session using the following ExceptionListener
method:
public void onException( JMSException exception )
The JMS Provider specifies the exception encountered that describes the problem when calling the method.
You can access the exception listener for a session using the following WLSession
method:
public ExceptionListener getExceptionListener( ) throws JMSException
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 using the Classic API.
Closing a Session
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 Session
method:
public void close( ) throws JMSException
Note:
The close()
method is the only Session method that can be invoked from a thread that is separate from the session thread.
This method does the following to execute an orderly shutdown:
-
Terminates the receipt of all pending messages. Applications can return a message or null if a message was not available at the time connection was closed.
-
Waits until all message listeners that are currently processing messages have completed.
-
Rolls back in-process transactions (unless these transactions are part of external JTA user transaction). For more information about JTA user transactions, see Using JTA User Transactions.
-
Does not force an acknowledgement of client acknowledged sessions, ensuring that no messages are lost for queues and durable subscriptions that require reliable processing.
When you close a session, all associated producers and consumers are also closed.
Note:
If you want to issue the close()
method within an onMessage()
method call, then the system administrator must select the Allow Close In OnMessage check box when configuring the connection factory.
Managing Destinations
Learn how to create and delete JMS destinations.
Dynamically Creating Destinations
See the following topics for information about creating destinations dynamically:
-
Using JMS Module Helper to Manage Applications briefs you about how to use the
weblogic.jms.extensions.JMSModuleHelper
. For more information about Using JMS Module Helper, see Using JMS Module Helper to Manage Applications -
Using Temporary Destinations briefs you about how applications are enabled to create destinations as per requirement. For more information about Using Temporary Destinations, seeUsing Temporary Destinations
The associated procedures for creating dynamic destinations are described in the following sections.
Dynamically Deleting Destinations
You can dynamically delete JMS destinations (queue or topic) using any of the following methods:
-
JMSModuleHelper class (see Using JMS Module Helper to Manage Applications)
-
Administration console
-
User-defined JMX application
The JMS server removes the deleted destination in real time, therefore, it is not necessary to redeploy the JMS server for the deletion to take effect.
Required Conditions for Deleting Destinations
In order to successfully delete a destination, the following conditions must be met:
-
The destination must not be a member of a distributed destination. For more information, see Using Distributed Destinations.
-
The destination must not be the error destination for some other destination. For more information, see Configuring an Error Destination for Undelivered Messages.
If either of these conditions cannot be met, then the deletion will not be allowed.
What Happens when a Destination Is Deleted
When a destination is deleted, the following behaviors and semantics apply:
-
Physical deletion of existing messages : All durable subscribers for the deleted destination are permanently deleted. All messages, persistent and non-persistent, stored in the deleted destination are permanently removed from the messaging system.
-
No longer able to create producers, consumers, and browsers : After a destination is deleted, applications will no longer be able to create producers, consumers, or browsers for the deleted destination. Any attempt to do so will result in the application receiving an
InvalidDestinationException
— as if the destination does not exist. -
Closing of consumers : All existing consumers for the deleted destination are closed. The closing of a consumer generates a
ConsumerClosedException
, which is delivered to theExceptionListener
, 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 anull
value indicating that no message is available. Attempts by an application to do anything butclose()
a closed consumer will result in anIllegalStateException
. -
Closing of browsers: All browsers for the deleted destination are closed. Attempts by an application to do anything but
close()
a closed browser will result in anIllegalStateException
. Closing of a browser implicitly closes all enumerations associated with the browser. -
Closing of enumerations : All enumerations for the deleted destination are closed. The behavior after an enumeration is closed depends on the last call before the enumeration was closed. If a call to
hasMoreElements()
returns a value of true, and no subsequent call tonextElement()
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 tohasMoreElements()
, and the value returned was true, then the following behaviors apply:-
The first call to the
nextElement()
will return a message. -
Subsequent calls to the
nextElement()
will throw aNoSuchElementException
. -
Calls to the
hasMoreElements()
made before the first call to thenextElement()
will return true. -
Calls to the
hasMoreElements()
made after the first call to thenextElement()
will return false.
If a given enumeration was never called, or the last call before the close was to
nextElement()
, or the last call before the close was to thehasMoreElements()
and the value returned was false, then the following behaviors apply:-
Calls to the
hasMoreElements()
will return false. -
Calls to the
nextElement()
will throw aNoSuchElementException
.
-
-
Blocking send operations cancelled — all blocking send operations posted against the deleted destination are cancelled. Send operations waiting for quota will receive a
ResourceAllocationException
. -
Uncommitted transactions unaffected : The deletion of a destination does not affect existing uncommitted transactions. Any uncommitted work associated with a deleted destination is allowed to complete as part of the transaction. However, because the destination is deleted, the net result of all operations (rollback, commit, and so on) is the deletion of the associated messages.
Message Timestamps for Troubleshooting Deleted Destinations
If a destination with persistent messages is deleted and then immediately re-created while the JMS server is not running, then the JMS server will compare the version number of the destination (using the CreationTime
field in the configuration config.xml
file) to 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 re-created destination, and when the JMS server is rebooted, the left over persistent messages are discarded.
However, if a persistent message somehow has a version number that is newer than the version number in the config.xml
for the re-created destination, then either the system clock was rolled back when the destination was deleted and re-created (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.
Deleted Destination Statistics
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 received in a transaction, as well as unacknowledged non-transactional messages received by a client.
Using Temporary Destinations
Temporary destinations enable an application to create a destination, as required, without the system administration overhead associated with configuring and creating a server-defined destination.
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 through the JMS server's Hosting Temporary Template
attribute. However, if you want to create temporary destinations with specific settings, you must 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 Oracle WebLogic Server Administration
Console Online Help.
The following sections describe how to create a temporary queue (Point-to-Point) or temporary topic (Publish/Subscibe).
Creating a Temporary Queue
You can create a temporary queue using the following QueueSession
method:
public TemporaryQueue createTemporaryQueue( ) throws JMSException
For example, to create a reference to a TemporaryQueue
that will exist only for the duration of the current connection, use the following method call:
QueueSender = Session.createTemporaryQueue();
Creating a Temporary Topic
You can create a temporary topic using the following TopicSession
method:
public TemporaryTopic createTemporaryTopic( ) throws JMSException
For example, to create a reference to a temporary topic that will exist only for the duration of the current connection, use the following method call:
TopicPublisher = Session.createTemporaryTopic();
Setting Up Durable Subscriptions
WebLogic JMS supports durable and non durable subscriptions. Learn how to set up durable subscriptions for your application.
For durable subscriptions, WebLogic JMS stores a message in a persistent file or database until the message is 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 Publish/Subscribe 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. 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.
The following sections describe:
Defining the Persistent Store
You must configure a persistent file or database store and assign it to your JMS server so WebLogic JMS can store a message until it is delivered to the subscribers or has expired.
-
Create a JMS file store or JMS JDBC backing store using the Stores node.
-
Target the configured store to your JMS server by selecting it from the Store field's drop-down list on the General tab of the configuration page under JMS Server.
Note:
No two JMS servers can use the same backing store.
Setting the Client ID Policy
The Client ID Policy specifies whether more than one JMS connection can use the same client ID in a cluster. Valid values for this policy are:
-
RESTRICTED
: The default. Only one connection that uses this policy can exist in a cluster at any given time for a particular client ID (If a connection already exists with a given Client ID, attempts to create new connections using this policy with the same client ID fail with an exception). -
UNRESTRICTED
: Connections created using this policy can specify any Client ID, even when other restricted or unrestricted connections already use the same client ID. When a durable subscription is created using an Unrestricted client ID, it can only be cleaned up usingweblogic.jms.extensions.WLJMSContext.unsubscribe(Topic topic, String name)
or usingweblogic.jms.extensions.WLSession.unsubscribe(Topic topic, String name)
. See Managing Durable Subscriptions.
Oracle recommends setting the client ID policy to Unrestricted
for new applications (unless your application architecture requires exclusive client IDs), especially if sharing a subscription (durable or non-durable). Subscriptions created with different client ID policies are always treated as independent subscriptions. See ClientIdPolicy
in the MBean Reference for Oracle WebLogic
Server.
To set the Client ID Policy
attribute on the connection factory using the WebLogic Console, see Configure multiple connections using the same client Id in the Oracle WebLogic Server Administration
Console Online Help. The connection factory setting can be overridden programatically using the setClientID
method of the WLConnection
interface in Java API Reference for Oracle
WebLogic Server.
For more information about advanced concepts and functionality of Uniform Distributed Topics (UDTs) necessary to design high availability applications, see Shared Subscriptions and Client ID Policy.
Defining the Client ID
To support durable subscriptions, a client identifier (client ID) must be defined for the connection.
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 set the JMS client ID to the WebLogic Server username, if it is appropriate for your JMS application.
The client ID can be supplied in two ways:
-
The first method is to configure the connection factory with the client ID. For WebLogic JMS, this means adding a separate connection factory definition during configuration for each client ID. Applications then look up their own topic connection factories in JNDI and use them to create connections that contain their own client IDs. See in Oracle WebLogic Server Administration Console Online Help.
-
Alternatively, the preferred method is for an application that can set its client ID in the connection after the connection is created by calling the following connection method:
public void setClientID( String clientID ) throws JMSException
If you use this alternative approach, then 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 the
setClientID()
method immediately after creating their topic connection.If a client ID is already defined for the connection, then an
IllegalStateException
is thrown. If the specified client ID is already defined for another connection, then anInvalidClientIDException
is thrown.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, then 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.To display a client ID and test whether or not a client ID has been defined already, use the following connection method:
public String getClientID( ) throws JMSException
Note:
Support for durable subscriptions is a feature unique to the Publish/Subscibe messaging model, so client IDs are used only with topic connections; queue connections also contain client IDs, but JMS does not use them.
Durable subscriptions should not be created for a temporary topic, because a temporary topic is designed to exist only for the duration of the current connection.
Creating a Sharable Subscription Policy
The Subscription Sharing policy specifies whether subscribers can share subscriptions with other subscribers on the same connections on this connection. Valid values for this policy are:
-
Exclusive
: The default. All subscribers created using this connection factory cannot share subscriptions with any other subscribers. Use this policy to retain the functionality of WebLogic Server 10.3.4.0 and earlier. -
Sharable
: Subscribers created using this connection factory can share their subscriptions with other subscribers, regardless of whether those subscribers are created using the same connection factory or a different connection factory. Consumers can share non durable subscriptions only if they have the same client ID and client ID policy; consumers can share a durable subscription only if they have the same client ID, client ID policy, and subscription name.
WebLogic JMS applications can override the Subscription Sharing policy specified on the connection factory configuration by casting a javax.jms.JMSContext
instance to weblogic.jms.extensions.WLJMSContext
or a javax.jms.Connection
instance to weblogic.jms.extensions.WLConnection
and calling setSubscriptionSharingPolicy(String subscriptionSharingPolicy)
.
Most applications with a Sharable Subscription Sharing policy will also use an Unrestricted client ID policy in order to ensure that multiple connections with the same client ID can exist.
Two durable subscriptions with the same client ID and subscription name are treated as two different independent subscriptions if they have a different Client ID Policy. Similarly, two Sharable non durable subscriptions with the same client ID are treated as two different independent subscriptions if they have a different client ID policy.
For more information on how to use the Subscription Sharing policy, see:
-
Configure a connection factory subscription sharing policy in Oracle WebLogic Server Administration Console Online Help.
Creating Subscribers for a Durable Subscription
This section describes how to create subscribers for a durable subscription and contains the following topics:
Using JMS 2.0 API
To create subscribers for an unshared durable subscription use one of the following methods:
public MessageConsumer createDurableConsumer( Topic topic, String name ) throws JMSException or public MessageConsumer createDurableConsumer( Topic topic, String name, String selector, boolean noLocal ) throws JMSException
Using JMS 1.1 API
You can create subscribers for a durable subscription using the following TopicSession
methods:
public TopicSubscriber createDurableSubscriber( Topic topic, String name ) throws JMSException or public TopicSubscriber createDurableSubscriber( Topic topic, String name, String messageSelector, boolean noLocal ) throws JMSException
You must specify the name of the topic for which you are creating a subscriber and the name of the durable subscription.
Note:
Valid durable subscription names cannot include the following characters: comma , equals, colon , asterisk , percent , or question mark.
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 selector
or messageSelector
,then 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 true
. The default for the noLocal
value is false
. Durable subscriptions are stored within the file or database.
Best Practice: Always Close Failed JMS ClientIDs
As a best practice, JMS clients should always call the close()
method instead of allowing the application to rely on the JVM's garbage collection to clean failed JMS connections. This is particularly important for durable subscription ClientIDs because the JMS Automatic Reconnect feature keeps a reference to failed JMS connections. Therefore, always use connection.close()
method to clean up your connections. Also, consider using a finally
block to ensure that your connection resources are cleaned up. Otherwise, WebLogic Server allocates system resources to keep the connection available.
The following code example demonstrates using theclose()
method and thefinally
block in a JMS client to clean up failed connection resources:
JMSConnection con = null; try { con = cf.createConnection(); con.setClientID("Fred"); // Do some I/O stuff; } finally { if (con != null) con.close(); }
For more information about the JMS Automatic Reconnect feature, see Automatic JMS Client Failover.
Deleting Durable Subscriptions
To delete a durable subscription, you use the following TopicSession
method:
public void unsubscribe( String name ) throws JMSException
You must specify the name of the durable subscription to be deleted.
You cannot delete a durable subscription if any of the following are true:
-
A
TopicSubscriber
is still active on the session. -
A message received by the durable subscription is part of a transaction or has not yet been acknowledged in the session.
Note:
You can also delete durable subscriptions from the WebLogic Server Administration Console. For information about managing durable subscriptions, see Managing Durable Subscriptions.
Managing Durable Subscriptions
You can monitor and manage durable topic subscribers using either the WebLogic Server 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 and Managing JMS Messages in Administering JMS Resources for Oracle WebLogic Server.
Setting and Browsing Message Header and Property Fields
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 through message selectors. Except for XML message extensions, data in the message body cannot be accessed through message selectors. For example, suppose you use a property field to assign high priority to a message. You can then design a message consumer that contains a message selector that accesses this property field and selects only messages of expedited priority. See Filtering Messages.
Setting Message Header Fields
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. After a message is received, its header field values can be modified.
When modifying (overriding) header field values, you must 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 send()
method.
For a description of the standard messages header fields, see Message Header Fields.
Table 6-3 lists the message class set and get methods for each of the supported data types.
Note:
In some cases, the send()
method overrides the header field value set using the set()
method, as indicated in the following table.
Table 6-3 JMS Header Field Methods
Header Field | Set Method | Get Method |
---|---|---|
JMSCorrelationID |
public void setJMSCorrelationID(String correlationID) throws JMSException |
public String getJMSCorrelationID() throws JMSException
|
JMSDestination Foot 1 |
public void setJMSDestination(Destination destination) throws JMSException |
public Destination getJMSDestination() throws JMSException |
JMSDeliveryMode1 |
public void setJMSDeliveryMode(int deliveryMode) throws JMSException |
public int getJMSDeliveryMode() throws JMSException |
JMSDeliveryTime1 |
public void setJMSDeliveryTime(long deliveryTime) throws JMSException |
public long getJMSDeliveryTime() throws JMSException |
JMSDeliveryMode1 |
public void setJMSDeliveryMode(int deliveryMode) throws JMSException |
public int getJMSDeliveryMode() throws JMSException |
JMSMessageID1 |
public void setJMSMessageID(String id) throws JMSException Note: In addition to the set method, the
|
public String getJMSMessageID() throws JMSException |
JMSPriority1 |
public void setJMSPriority(int priority) throws JMSException |
public int getJMSPriority() throws JMSException |
JMSRedelivered1 |
public void setJMSRedelivered(boolean redelivered) throws JMSException |
public boolean getJMSRedelivered() throws JMSException |
JMSRedeliveryLimit1 |
public void setJMSRedeliveryLimit(int redelivered) throws JMSException |
public int getJMSRedeliveryLimit() throws JMSException |
JMSReplyTo |
public void setJMSReplyTo(Destination replyTo) throws JMSException |
public Destination getJMSReplyTo() throws JMSException |
JMSTimeStamp1 |
public void setJMSTimeStamp(long timestamp) throws JMSException |
public long getJMSTimeStamp() throws JMSException |
JMSType |
public void setJMSType(String type) throws JMSException |
public String getJMSType() throws JMSException |
Footnote 1
The corresponding 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 send()
operation.
The examples.jms.sender.SenderServlet
example, provided with WebLogic Server in the EXAMPLES_HOME
\wl_server\examples\src\examples\jms\sender
directory, where EXAMPLES_HOME
represents the directory in which the WebLogic Server code examples are configured, shows how to set header fields in messages that you send and how to display message header fields after they are sent.
For example, the following code, which appears after the send()
method, displays the message ID that was assigned to the message by WebLogic JMS:
System.out.println("Sent message " + msg.getJMSMessageID() + " to " + msg.getJMSDestination());
Setting Message Property Fields
To set a property field, call the appropriate set method and specify the property name and value. To read a property field, call the appropriate get method
and specify the property name.
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 clearProperties()
method:
public void clearProperties( ) throws JMSException
This method does not clear the message header fields or body.
Note:
The 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 JMS_
property name prefix is reserved for provider-specific properties; it is not intended for use with standard JMS messaging.
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.
Table 6-4 Message Property Set and Get Methods for Data Types
Data Type | Set Method | Get Method |
---|---|---|
boolean |
public void setBooleanProperty( String name, boolean value ) throws JMSException |
public boolean getBooleanProperty( String name ) throws JMSException |
byte |
public void setByteProperty( String name, byte value ) throws JMSException |
public byte getByteProperty( String name ) throws JMSException |
double |
public void setDoubleProperty( String name, double value ) throws JMSException |
public double getDoubleProperty( String name ) throws JMSException |
float |
public void setFloatProperty( String name, float value ) throws JMSException |
public float getFloatProperty( String name ) throws JMSException |
int |
public void setIntProperty( String name, int value ) throws JMSException |
public int getIntProperty( String name ) throws JMSException |
long |
public void setLongProperty( String name, long value) throws JMSException |
public long getLongProperty( String name ) throws JMSException |
short |
public void setShortProperty( String name, short value ) throws JMSException |
public short getShortProperty( String name ) throws JMSException |
String |
public void setStringProperty( String name, String value ) throws JMSException |
public String getStringProperty( String name ) throws JMSException |
In addition to the set
and get methods
described in the previous table, you can use the setObjectProperty()
and 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.
You can access all property field names using the following Message method:
public Enumeration getPropertyNames( ) throws JMSException
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 Table 6-4, based on the property field data type.
Table 6-5 contains a conversion chart for message properties. It enables you to identify the type that can be read based on the type that has been written. For each property type listed in the left-most column in which a message has been written, a YES in one of the remaining columns indicates that the message can be read as the type listed at the top of that column.
Table 6-5 Message Property Conversion Chart
Property Written As. . . | boolean | byte | double | float | int | long | short | String |
---|---|---|---|---|---|---|---|---|
boolean |
YES |
No |
No |
No |
No |
No |
No |
YES |
byte |
No |
YES |
No |
No |
YES |
YES |
YES |
YES |
double |
No |
No |
YES |
No |
No |
No |
No |
YES |
float |
No |
No |
YES |
YES |
No |
No |
No |
YES |
int |
No |
No |
No |
No |
YES |
YES |
No |
YES |
long |
No |
No |
No |
No |
No |
YES |
No |
YES |
Object |
YES |
YES |
YES |
YES |
YES |
YES |
YES |
YES |
short |
No |
No |
No |
No |
YES |
YES |
YES |
YES |
String |
YES |
YES |
YES |
YES |
YES |
YES |
YES |
YES |
You can test whether or not a property value was set using the following Message
method:
public boolean propertyExists( String name ) throws JMSException
You specify a property name and the method returns a Boolean value indicating whether or not the property exists.
For example, the following code sets two String
properties and an int
property:
msg.setStringProperty("User", user); msg.setStringProperty("Category", category); msg.setIntProperty("Rating", rating);
For more information about message property fields, see Message Property Fields, or the javax.jms.Message
Javadoc at http://docs.oracle.com/javaee/7/api/javax/jms/Message.html
.
Browsing Header and Property Fields
Note:
Only queue message header and property fields can be browsed. You cannot browse topic message header and property fields.
You can browse the header and property fields of messages on a queue using the following QueueSession
methods:
public QueueBrowser createBrowser( Queue queue ) throws JMSException public QueueBrowser createBrowser( Queue queue, String messageSelector ) throws JMSException
You must specify the queue that you want to browse. You can also specify a message selector to filter messages that you are browsing. Message selectors are described in more detail in Filtering Messages.
After you define a queue, you can access the queue name and message selector associated with a queue browser using the following QueueBrowser
methods:
public Queue getQueue( ) throws JMSException public String getMessageSelector( ) throws JMSException
In addition, you can access an enumeration for browsing the messages using the following QueueBrowser
method:
public Enumeration getEnumeration( ) throws JMSException
The examples.jms.queue.QueueBrowser
example, provided with WebLogic Server in the EXAMPLES_HOME
\wl_server\examples\src\examples\jms\queue
directory, where EXAMPLES_HOME
represents the directory in which the WebLogic Server code examples are configured, shows how to access the header fields of received messages.
For example, the following code is an excerpt from the QueueBrowser
example and creates the QueueBrowser
object:
qbrowser = qsession.createBrowser(queue);
The following is 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.
public void displayQueue( ) throws JMSException { Enumeration e = qbrowser.getEnumeration(); Message m = null; if (! e.hasMoreElements()) { System.out.println("There are no messages on this queue."); } else { System.out.println("Queued JMS Messages: "); while (e.hasMoreElements()) { m = (Message) e.nextElement(); System.out.println("Message ID " + m.getJMSMessageID() + " delivered " + new Date(m.getJMSTimestamp()) " to " + m.getJMSDestination()); } }
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 at http://docs.oracle.com/javaee/7/api/javax/jms/QueueBrowser.html
.
Filtering Messages
In many cases, an application does not need to be notified of every message that is delivered to it. Use message selectors to filter unwanted messages, and subsequently improve performance by minimizing their effect on network traffic.
Message selectors operate as follows:
-
The sending application sets message header or property fields to describe or classify a message in a standardized way.
-
The receiving applications specify a simple query string to filter the messages that they want to receive.
Because message selectors cannot reference the contents (body) of a message, some information may be duplicated in the message property fields (except in the case of XML messages).
You specify a selector when creating a queue receiver or topic subscriber, as an argument to the QueueSession.createReceiver()
or TopicSession.createSubscriber()
methods, respectively. For information about creating queue receivers and topic subscribers, see Step 5: Create Message Producers and Message Consumers.
WebLogic JMS assigns a state or current processing condition to messages during processing. You can use these states as selectors. For information on valid message states, see weblogic.jms.extensions.JMSMessageInfo in Java API Reference for Oracle WebLogic Server.
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.
Defining Message Selectors Using SQL Statements
A message selector is a Boolean expression. It consists of a String with a syntax similar to the where
clause of an SQL select
statement.
The following excerpts provide examples of selector expressions.
salary > 64000 and dept in ('eng','qa') (product like 'WebLogic%' or product like '%T3') and version > 3.0 hireyear between 1990 and 1992 or fireyear is not null fireyear - hireyear > 4
The following example shows how to set a selector when creating a queue receiver that filters out messages with a priority lower than 6.
String selector = "JMSPriority >= 6"; qsession.createReceiver(queue, selector);
The following example shows how to set the same selector when creating a topic subscriber.
String selector = "JMSPriority >= 6"; qsession.createSubscriber(topic, selector);
For more information about the message selector syntax, see the javax.jms.Message
Javadoc at http://docs.oracle.com/javaee/7/api/javax/jms/Message.html
.
Defining XML Message Selectors Using XML Selector Method
For XML message types, in addition to using the SQL selector expressions described in the previous section to define message selectors, you can use the following method:
String JMS_BEA_SELECT(String type, String expression)
The 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
.
Note:
Pay careful attention to your XML message syntax, since malformed XML messages (for example, a missing end tag) will not match any XML selector.
The method returns a null value under the following circumstances:
-
The message does not parse.
-
The message parses, but the element is not present.
-
If a message parses and the element is present, but the message contains no value (for example,
<order></order>
).
For example, consider the following XML code example:
<order> <item> <id>007</id> <name>Hand-held Power Drill</name> <description>Compact, assorted colors.</description> <price>$34.99</price> </item> <item> <id>123</id> <name>Mitre Saw</name> <description>Three blades sizes.</description> <price>$69.99</price> </item> <item> <id>66</id> <name>Socket Wrench Set</name> <description>Set of 10.</description> <price>$19.99</price> </item> </order>
The following example shows how to retrieve the name of the second item in the previous example. This method call returns the string, Mitre Saw
.
String sel = "JMS_BEA_SELECT('xpath', '/order/item[2]/name/text()') = 'Mitre Saw'";
Pay careful attention to the use of double and single quotation mark and spaces. Note the use of single quotation mark around xpath
, the XML tab, and the string value.
The following example shows how to retrieve the ID of the third item in the previous example. This method call returns the string, 66
.
String sel = "JMS_BEA_SELECT('xpath', '/order/item[3]/id/text()') = '66'";
Displaying Message Selectors
You can use the following MessageConsumer
method to display a message selector:
public String getMessageSelector( ) throws JMSException
This method returns either the currently defined message selector or null if a message selector is not defined.
Indexing Topic Subscriber Message Selectors to Optimize Performance
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.
To activate optimized subscriber message selectors, subscribers must use the following syntax for their selectors:
"identifier IS NOT NULL"
identifier
is an arbitrary string that is not a predefined JMS message property (e.g., neither JMSCorrelationID
nor JMSType
). Multiple subscribers can share the same identifier.
WebLogic JMS uses this message selector syntax as a hint to build internal subscriber indexes. Message selectors that do not follow the syntax, or that include additional OR
and AND
clauses, are still honored, but do not activate the optimization.
After subscribers register 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 shown in the following example:
// Set up a named subscriber, where "wilma" is the name of // the subscriber and subscriberSession is a JMS TopicSession. // Note that the selector syntax used activates the optimization. TopicSubscriber topicSubscriber = subscriberSession.createSubscriber( (Topic)context.lookup("IMTopic"), "Wilma IS NOT NULL", /* noLocal= */ true); // Send a message to subscribers "Fred" and "Wilma", // where publisherSession is a JMS TopicSession. Subscribers // with message selector expressions "Wilma IS NOT NULL" // or "Fred IS NOT NULL" will receive this message. TopicPublisher topicPublisher = publisherSession.createPublisher( (Topic)context.lookup("IMTopic"); TextMessage msg = publisherSession.createTextMessage("Hi there!"); msg.setBooleanProperty("Fred", true); msg.setBooleanProperty("Wilma", true); topicPublisher.publish(msg);
Note:
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, and 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 for the enhancement anyway, because the message selection occurs on the client side rather than on the server side.
Sending XML Messages
The WebLogic Server JMS API provides native support for the Document Object Model (DOM) to send XML messages.
Note:
This release does not support streaming. Only text and DOM representations of XML documents are supported.
The following sections provide information on WebLogic JMS API extensions that provide enhanced support for XML messages.
WebLogic XML APIs
You can use the following WebLogic XML APIs for transformation of XML between String
and DOM
representations:
-
XMLMessage
: Use to send messages with XML content. -
WLSession.createXMLMessage
: Use to create an XML message.
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.
Using a String Representation
Use the following steps to publish an XML message using a string
type:
- Serialize the XML to a
StringWriter
. - Call the
toString
on theStringWriter
and pass it into themessage.setText
. - Publish the message.
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:
- If necessary, generate a DOM document from your XML source.
- Pass the DOM document into the
XMLMessage.setDocument
. - Publish the message.