3 Best Practices for Application Design

Learn about the design options for WebLogic Server JMS, application behaviors to be considered during the design process, and the recommended design patterns.

Message Design

Learn how to design messages to improve messaging performance.

Serializing Application Objects

The CPU cost of serializing Java objects can be significant. This expense, in turn, affects JMS Object messages. You can offset some of this cost by having application objects implement thejava.io.Externalizable, but there still will be significant overhead in marshalling the class descriptor. To avoid the cost of having to write the class descriptors of additional objects embedded in an Object message, have these objects implement Externalizable, and call readExternal and writeExternal on them directly. For example, call obj.writeExternal(stream) rather than the stream.writeObject(obj). Using Bytes and Stream messages is generally a preferred practice.

Serializing Strings

Serializing Java strings is more expensive than serializing other Java primitive types. Strings are also memory intensive; they consume two bytes of memory per Character, and cannot compactly represent binary data (integers, for example). In addition, the introduction of string-based messages often implies an expensive parse step in the application in order to process the String into something the application can make direct use of. Bytes, Stream, Map and Object messages are therefore sometimes preferable to Text and XML messages. Similarly, it is preferable to avoid the use of strings in message properties, especially if they are large.

Server-side Serialization

WebLogic JMS servers do not incur the cost of serializing non persistent messages. Serialization of non persistent message types is incurred by the remote client. Persistent messages are serialized by the server.


Using a selector is expensive. This consideration is important when you are deciding where in the message to store application data that is accessed through JMS selectors.

Message Compression

Compressing large messages in a JMS application can improve performance.

Message compression reduces the amount of time required to transfer messages across the network, reduces the amount of memory used by the JMS server, and, if the messages are persistent, reduces the size of persistent writes. Text and XML messages can often be compressed significantly. Of course, compression is achieved at the expense of an increase in the CPU usage of the client.

Keep in mind that the benefits of compression become questionable for smaller messages. If a message is less than a few KB in size, then compression can actually increase its size. The JDK provides built-in compression libraries. For details, see the java.util.zip package.

For information about using JMS connection factories to specify the automatic compression of messages that exceed a specified threshold size, see Compressing Messages in the Tuning Performance of Oracle WebLogic Server.

Message Properties and Message Header Fields

Instead of user-defined message properties, consider using standard JMS message header fields or the message body for message data. Message properties incur an extra cost in serialization, and are more expensive to access than standard JMS message header fields.

Avoid embedding large amounts of data in the properties field or the header fields; only message bodies are paged out when paging is enabled. Consequently, if user defined message properties are defined in an application, avoid the use of large string properties.

See Message Header Fields and Message Property Fields.

Message Ordering

You should use the Message Unit-of-Order feature rather than Ordered Redelivery to guarantee ordered message processing.

The advantages of Message Unit-of-Order over Ordered Redelivery are:

  • Ease of configuration.

    • Does not require a custom connection factory for asynchronous receivers, such as setting the MessagingMaximum to 1 when using message-driven beans (MDBs).

    • Simple configuration when using distributed destinations.

  • Preserves message order during processing delays.

  • Preserves message order during transaction rollback or session recovery.

Oracle recommends applications that use Ordered Redelivery upgrade to Message Unit-of-Order. See Using the Message Unit-of-Order.

Topics Vs. Queues

When you start to design your application, it is not always immediately obvious whether it would be better to use a Topic or Queue.

You should use a Topic only if one of the following conditions applies:

  • The same message must be replicated to multiple consumers.

  • A message should be dropped if there are no active consumers that will select it.

  • There are many subscribers, each with a unique selector.

Note that a topic with a single durable subscriber is semantically similar to a queue. The differences are as follows:

  • If you change a topic selector for a durable subscriber, then all previous messages in the subscription are deleted, while if you change a queue selector for consumer, then no messages in the queue are deleted.

  • A queue may have multiple consumers, and will distribute its messages in a round-robin fashion, whereas a topic subscriber is limited to one consumer.

For more information about configuring JMS queues and topics, see Queue and Topic Destination Resources in Administering JMS Resources for Oracle WebLogic Server.

Asynchronous Vs. Synchronous Consumers

In general, asynchronous (onMessage) consumers perform and scale better than synchronous consumers.

  • Asynchronous consumers create less network traffic. Messages are pushed unidirectionally, and are pipelined to the message listener. Pipelining supports the aggregation of multiple messages into a single network call.


    In WebLogic Server, your synchronous consumers can also use the same efficient behavior as asynchronous consumers by enabling the Prefetch Mode for Synchronous Consumers option on JMS connection factories, as described in Use Prefetch Mode to Create a Synchronous Message Pipeline.

  • Asynchronous consumers use fewer threads. An asynchronous consumer does not use a thread while it is inactive. A synchronous consumer consumes a thread for the duration of its receive call. As a result, a thread can remain idle for long periods, especially if the call specifies a blocking timeout.

  • For application code that runs on a server, it is almost always best to use asynchronous consumers, typically through MDBs. The use of asynchronous consumers prevents the application code from doing a blocking operation on the server. A blocking operation, in turn, idles a server-side thread; it can even cause deadlocks. Deadlocks occur when blocking operations consume all threads. When no threads remain to handle the operations required to unblock the blocking operation itself, that operation never stops blocking.

For more information, see Receiving Messages Asynchronously using the Classic API and Receiving Messages Synchronously Using the Classic API.

Persistent Vs. Non Persistent Messages

When designing an application, make sure you specify that messages will be sent in non persistent mode unless a persistent QOS is required.

Oracle recommends non persistent mode because unless synchronous writes are disabled, a persistent QOS can cause a significant degradation in performance.


Avoid persisting sending persistent messages unintentionally. Occasionally an application sends persistent messages even though the designer intended the messages to be sent in non persistent mode.

If your messages are truly non persistent, none should end up in a regular JMS store. To make sure that none of your messages are persistent, check whether the JMS store size grows when unconsumed messages are accumulating on the JMS server. Here is how message persistence is determined, in order of precedence:

  • Producer's connection's connection factory configuration:

    • PERSISTENT (default)


  • JMS Producer API override on QueueSender and TopicPublisher:

    • setDeliveryMode(DeliveryMode.PERSISTENT)

    • setDeliveryMode(DeliveryMode.NON_PERSISTENT)

    • setDeliveryMode(DeliveryMode.DEFAULT_DELIVERY_MODE) (default)

  • JMS Producer API per message override on QueueSender and TopicPublisher:

    • For queues, optional deliveryMode parameter on send()

    • For topics, optional deliveryMode parameter on publish()

  • Override on destination configuration:

    • Persistent

    • Non Persistent

    • No Delivery (default, implies no override)

  • Override on JMS server configuration:

    • If store is configured then that implies using the default persistent store that is available on each targeted WebLogic Server instance

    • If a Store is configured then that implies no override.

  • Non durable subscribers only:

    • If there are no subscribers, or there are only non durable subscribers for a topic, the messages will be downgraded to non persistent. (Because non durable subscribers exist only for the life of the JMS server, there is no reason for the message to persist.)

  • Temporary destinations:

    • Because temporary destinations exist only for the lifetime of their host JMS server, there is no reason for messages to persist. WebLogic JMS automatically forces all messages in a temporary destination to non-persistent.

Durable subscribers require a persistent store to be configured on their JMS server, even if they receive only non persistent messages. A durable subscription persists to ensure that it continues through a server restart, as required by the JMS specification.

Deferring Acknowledges and Commits

Because sending is generally faster than receiving , consider reducing the overhead associated with receiving by deferring acknowledgment of messages until several messages have been received and can be acknowledged collectively.

If you are using transactions, then substitute the word commit for acknowledge.

Deferment of acknowledgements is not likely to improve performance for non durable subscriptions, because of the internal optimizations already in place.

It may not be possible to implement deferred acknowledgements for asynchronous listeners. If an asynchronous listener acknowledges only every 10 messages, but for some reason receives only 5, then the last few messages may not be acknowledged. One possible solution is to have the asynchronous consumer post synchronous, non blocking receives from within its onMessage() callback to receive subsequent messages. Another possible solution is to have the listener start a timer that, when triggered, sends a message to the listener's destination in order to wake it up and complete the outstanding work that has not yet been acknowledged—assuming that the wake-up message can be directed at the correct listener.

Using AUTO_ACK for Non Durable Subscribers

Non durable, non transactional topic subscribers are optimized to store local copies of the message on the client side, thus reducing network overhead when acknowledgements are being issued.

This optimization yields a 10-20 percent performance improvement, where the improvement is more evident under higher subscriber loads.

One side effect of this optimization, particularly for high numbers of concurrent topic subscribers, is the overhead of client-side garbage collection, which can degrade performance for message subscriptions. To prevent such degradation, Oracle recommends allocating a larger heap size on the subscriber client. For example, in a test of 100 concurrent subscribers running in 10 JVMs, it was found that giving clients an initial and maximum heap size of 64MB for each JVM was sufficient.

Alternative Qualities of Service, Multicast and No-Acknowledge

WebLogic JMS provides alternative qualities of service (QOS) extensions that can help performance.


Non durable topic subscribers can subscribe to messages using the MULTICAST_NO_ACKNOWLEDGE. If a topic has such subscribers, then the JMS server will broadcast messages to them using multicast mode. Multicast improves performance considerably and provides linear scalability, as the network only needs to handle one message, regardless of the number of subscribers, rather than one message per subscriber. Multicast messages may be lost if the network is congested or if the client falls behind in processing them. Calls to recover() or acknowledge() have no effect on multicast messages.


On the client side, each multicasting session requires a dedicated thread to retrieve messages off the multicast socket. Therefore, you should increase the JMS client-side thread pool size to adjust for this.

This QOS extension has the same level of guarantee as some JMS implementations default QOS from vendors other than Oracle WebLogic Server for non durable topic subscriptions. The JMS 1.1 specification specifically allows non durable topic messages to be dropped (deleted) if the subscriber is not ready for them. WebLogic JMS has a higher QOS for non durable topic subscriptions by default than the JMS 1.1 specification requires.


A no-acknowledge delivery mode implies that the server gives messages to consumers, but does not expect an acknowledgement to be called. Instead, the server pre-acknowledges the message. In this acknowledge mode, calls to recover will not work, because the message was acknowledged. This mode saves the overhead of an additional network call to the acknowledge, at the expense of possibly losing a message when a server failure, a network failure, or a client failure occurs.


If an asynchronous client calls theclose() in this scenario, then all messages in the asynchronous pipeline are lost.

Asynchronous consumers that use a NO_ACKNOWLEDGE QOS may want to reduce their message pipeline size in order to lower the number of lost messages in the event of a failure.

Avoid Multi threading

The JMS specification states that multi threading a session, producer, consumer, or message method results in undefined behavior except when calling close().

See the specification at http://www.oracle.com/technetwork/java/jms/index.html. If your application is thread limited, then try increasing the number of producers and sessions.

Using the JMSXUserID Property

For WebLogic Server 9.0 and later, you can configure a JMS connection factory and destination to automatically propagate the message sender's authenticated username. The username is placed in a javax.jms.Message property named JMSXUserID.

Consider the following points when using the JMSXUserID property in your application.

  • While the JMS specification makes some mention of the JMSXUserID property, the behavior is lightly defined and will likely be different for different JMS vendors.

  • The JMSXUserID property is based on the credential of the thread an application uses to create the JMS producer. It does not derive from the credential that is on a thread during the JMS send call itself.

  • JMS will ignore or override any attempt by an application to directly set JMSXUserID (for example, javax.jms.Message.setXXXProperty() will not work).

  • JMS messages are not signed or encrypted (similar to any RMI/EJB call). Therefore, fully secure transfers of the JMSXUserID require sending the message through secure protocols (for example, t3s or https).

  • WebLogic Store-and-Forward agents do not propagate the JMSXUserID (they null it out).

  • WebLogic Messaging bridges will propagate JMSXUserID property of the source destination's message if the messaging bridges are both are forwarding to a 9.0 or later JMS server and are configured to Preserve Message Properties. Otherwise, the forwarded message will either contain no username or the username used by the bridge sender. The latter behavior is determined by the configuration of the bridge sender's connection factory and destination.

  • The WebLogic JMS WLMessageProducer.forward() extension can forward a received message's JMSXUserID.


    The JMSXUserID property interoperability behavior for WebLogic JMS clients prior to 9.0 is undetermined.

For instructions about setting the JMSXUserID property on a connection factory or a destination, see the following topics in the WebLogic Server Administration Console online help:

Performance and Tuning

Implement the performance tuning features available with WebLogic JMS and get the most out of your applications.

See Tuning WebLogic JMS in Tuning Performance of Oracle WebLogic Server.