Skip navigation.

WebLogic Server Frequently Asked Questions

  Previous Next vertical dots separating previous/next from contents/index/pdf Contents View as PDF   Get Adobe Reader

FAQs: JMS

The WebLogic JMS Product

Configuration

Persistent Stores

Administration

Transaction Support

JMS Programming Practices

Message-Driven Beans


Q. What makes WebLogic JMS unique?

A. There are numerous features that make WebLogic JMS unique. For a complete listing, see "Introduction to WebLogic JMS" in Programming WebLogic JMS.


Q. Where can I learn more about WebLogic JMS?

A. The following links provide more information about WebLogic JMS:


Q. Is there a C/C++ interface to WebLogic JMS?

A. Yes, there is a JMS C client available on the dev2dev Utility and Tools page, which has a downloadable jmscapi.zip file that includes all the necessary files, as well as documentation and samples. This is not a supported product of BEA. However, if you have questions about this API you can post them to WebLogic JMS "weblogic.developer.interest.jms" newsgroup available on the BEA Newsgroup server.


Q. Is there a smaller version of the weblogic.jar file for supporting clients?

A. Yes. WebLogic Server 8.1 provides a true J2EE application client. The WebLogic Server application client is provided as a standard client and a JMS client, packaged as two separate jar files—wlclient.jar and wljmsclient.jar—in the /server/lib subdirectory of the WebLogic Server installation directory. Each jar is about 400 KB.


Q. How do I start WebLogic Server and configure JMS?

A. Refer to "Starting WebLogic Server and Configuring JMS" in the Programming WebLogic JMS for detailed instructions on starting WebLogic Server, accessing the Administration Console, and configuring a basic Weblogic JMS implementation.


Q. How do I configure WebLogic JMS security?

A. A security policy is created when you define an association between a WebLogic resource and a user, group, or role. A WebLogic resource has no protection until you assign it a security policy. You can assign a security policy to any WebLogic JMS destination using the administration console.

Using the navigation tree, access your JMS destinations, which are under Services —> JMS —> Servers —> <server name> —> Destinations. Right-click a destination, and then select Define policy from the pop-up menu. By default, the console screen sets a policy for all operations on each destination. You may also set separate policies for the send(), receive(), and browse() operations on the destination using the list box labeled Methods.

For instructions on how to set up security for all WebLogic Server resources, see "Securing WebLogic Resources".


Q. Can I still use the default connection factories supported in WebLogic JMS 5.1?

A. Yes. For detailed information about using 5.1 connection factories in later versions of WebLogic JMS, see "Porting WebLogic JMS Applications" in Programming WebLogic JMS.


Q. Why does JMSSession.createTopic or JMSSession.createQueue fail to create a destination in WebLogic JMS 8.1? (It worked in version 5.1?)

A. For a detailed explanation of this issue, refer to the JMS FAQ in the version 6.1 Frequently Asked Questions.


Q. How do I programmatically get a list of queues or topics?

A. There are JMS Helper methods that allow you to locate JMS runtime and configuration JMX MBeans. There are also methods for dynamically creating and deleting JMS queue and topic destinations, as described in the JMS Helper Method Javadoc.


Q. How do I use a temporary destination?

A. You must create a template on every JMSServer where you want to be able to create temporary destinations. You can specify multiple JMSServer entries to support a Temporary Template and the system will load balance among those JMSServers to set up the temporary destination. See How do I start WebLogic Server and configure JMS? for a description about how to configure JMS. The resulting template definition looks something like the following:

<JMSTemplate  Name="MyTemplate"/>

The JMSServer is defined something like:

<JMSServer Name="MyJMSServer" TemporaryTemplate="MyTemplate" Targets="MyServer" >

After the template name, you can set any queue/topic attribute you want in the template (not including a JNDI name or topic multicast settings). The template is at the outer most level; that is, it should not be nested in your <JMSServer>.

Temporary destinations can only be consumed by the creating connection. Using topics, you create your temporary topic and subscribe to that temporary topic. If you want someone to publish to that temporary topic, you need to tell that someone what your topic is. You can send them a message and include your temporary topic in the JMSReplyTo field. The creator of the TemporaryTopic and the subscriber must be one in the same.

import javax.jms.TopicSession;
TemporaryTopic myTopic = mySession.createTemporaryTopic();
TopicSubscriber = mySession.createSubscriber(myTopic);

Temporary topics do not get names and cannot be subscribed to by other connections. When you create a temporary topic, the JMS provider returns a javax.jms.Topic. You then need to advertise that topic to other parties (those who want to publish to the topic), putting it in your JMSReplyTo field so that they can respond. In general, no one else can subscribe to the topic. You advertise the topic any way you want. Topics are Serializable (or in our case, Externalizable), which allows you to pass them around in RMI calls, through a file, binding it to a name in JNDI, etc. In short, create the topic at the subscriber side and advertise so that others can publish. You can get multiple subscribers on the same connection and get concurrent processing using multiple sessions.

For more information about using temporary destinations, see "Using Temporary Destinations" in Programming WebLogic JMS.


Q. How do I use MBeans to print runtime statistics?

A. BEA's dev2dev Web site contains a "JMS Statistics View" program to print JMS statistics based on run-time MBeans. Also, there are JMS Helper methods that allow you to access run-time statistics for JMS connection, destination, consumer, and producer MBeans, as described in the JMS Helper Method Javadoc.


Q. Can two JMS servers share the same persistent store?

A. No. Each JMS server must have its own unique persistent store. Two file-based JMS persistent stores may share the same directory, but their messages will be stored in different files. In this case, the filenames will contain different prefixes.

Two JDBC-based JMS persistent stores may share the same database, but they must be configured to use a different Prefix Name which will be prepended to the database tables. For more information on configuring the JDBC Prefix Name, see "Using Prefixes With JMS JDBC Stores" in the Administration Console Online Help. If they are configured with the same Prefix Name, persistent messages will be corrupted and/or lost.


Q. Which types of JDBC databases does WebLogic JMS support?

A. The JMS database can be any database that is accessible through a JDBC driver. For a list of drivers that WebLogic JMS detects, see "JMS JDBC Store Tasks" in the Administration Console Online Help.


Q. How do I use a third-party JDBC driver with WebLogic JMS?

A. If your JDBC driver is not included in the list of drivers in the question about JDBC databases supported by WebLogic JMS, then the tables required by JMS must be created manually. Follow the procedures in JDBC Database Utility in Programming WebLogic JMS to manually create the database tables for the JDBC store.

Note: WebLogic Server only guarantees support for the JDBC drivers listed in "JMS JDBC Stores Tasks" in the Administration Console Online Help. Support for any other JDBC driver is not guaranteed.

Another option is to consider using a JMS file store instead of a JMS JDBC store. File stores are easier to configure and may provide significantly better performance.


Q. What if my JDBC database becomes corrupt?

A. The procedures for removing and regenerating the JDBC store tables or creating the database tables manually are described in detail in JDBC Database Utility in Programming WebLogic JMS.


Q. How do I use persistence?

A. Use the following guidelines:

  1. Make sure the JMSServer you are using has a store configured. The JMSServer configuration entry in the config.xml file should contain a line of the form
  2. Store="<YOUR-STORE-NAME>" 

    Note that if JMS boots without a store configured, it is assumed the customer did not want one, and persistent messages are silently downgraded to non-persistent (as specified for JMS 1.0.2b).

  3. Make sure you are not using "Message.setJMSDeliveryMode". This is overwritten, as it is a vendor-only method.
  4. Make sure you are calling either:
  5. QueueSender.send(msg, deliveryMode, ...)

    -- or --

    QueueSender.setDeliveryMode(deliveryMode)

    -- or --

    set DefaultDeliveryMode mode on connection factory in the config.xml file to persistent (the QueueSender.setDeliver/send overrides this value). Similarly, for topics, you would set this via the TopicPublisher.

  6. Make sure you don't have "DeliveryModeOverride" set to Non-Persistent on the Destination in the config.xml file.
  7. If you are using pub/sub, only durable subscriptions persist messages. Non-durable subscriptions have no need to persist messages, as by definition they only exist for the life of the server.

See the question, How do I start WebLogic Server and configure JMS? for a description of how to configure JMS.


Q. How does a file store compare with a JDBC store?

A. The are a number of similarities and differences between file stores and JDBC stores. For a complete listing, see "JMS Stores Tasks" in the Administration Console Online Help.


Q. How important is it to keep the system clocks synchronized among server instances hosting distributed destination members and their connection factories?

A. It is very important when using distributed topics with non-durable subscribers. This is because if the clocks between the servers become too far askew, there is a possibility that messages will not be delivered. Here's how this could happen: both the connection factory for the distributed topic and the distributed topic members will use their local system clock to see if a consumer is created after a message is published. Messages published to topics before consumers are created are not visible to consumers. There is always a race in any topic when the message is published before the consumer is created.

Distributed topics widen this race when the system clocks on the server instances hosting the connection factory or the distributed topic members are not in sync. For example, if your application creates short-lived, non-durable topic consumers, and a consumer is listening through a connection factory on ServerA, but the message is published to distributed topic member on ServerB, and the clocks from ServerA and ServerB are out of sync (more than the life of the topic consumer you have created), then that consumer will not receive the message sent due to the difference in the system clocks.


Q. Why am I getting "out of memory" errors?

A. The byte and message maximum values are quotas - not flow control. Message quotas prevent a WebLogic JMS server from filling up with messages and possibly running out of memory, causing unexpected results. Unless the "Blocking Sends" feature has been implemented, when you reach your quota, JMS prevents further sends with a ResourceAllocationException (rather than blocking). You can set quotas on individual destinations or on a server as a whole. For more information on configuring the "Blocking Sends" feature, see "Avoiding Quota Exceptions by Blocking Message Producers" in the Administration Console Online Help.

The thresholds are also not flow control - though they would be better suited to that application than the quotas. The thresholds are simply settings that when exceeded cause a message to be logged to the console to let you know that you are falling behind.

WebLogic JMS also has a flow control feature that enables a JMS server or destination to slow down message producers when it is becoming overloaded. Specifically, when a JMS server/destination exceeds its specified bytes or messages thresholds, it instructs producers to limit their message flow. For more information, see "Controlling the Flow of Messages on JMS Servers and Destinations" in the Administration Console Online Help.

Note: The messages maximum setting on a connection factory is not a quota. This specifies the maximum numbers of outstanding messages that can exist after they have been pushed from the server but before an asynchronous consumer has seen them; it defaults to a value of 10.


Q. What is the value of clustering for WebLogic JMS?

A. In version 6.x, you could establish cluster-wide, transparent access to destinations from any server in the cluster by configuring multiple connection factories and using targets to assign them to WebLogic Servers, as described in "Configuring WebLogic JMS Clustering" in the Programming WebLogic JMS. Each connection factory can be deployed on multiple WebLogic Servers, serving as connection concentrators. You could configure multiple JMS servers on the various nodes in the cluster—as long as the servers are uniquely named—and can then assign destinations to the various JMS servers.

For WebLogic JMS 7.0 or later, you can also configure multiple destinations as part of a single distributed destination set within a cluster. Producers and consumers are able to send and receive through a distributed destination. In the event of a single server failure within the cluster, WebLogic JMS then distributes the load across all available physical destinations within the distributed destination. For more information, see "Distributed Destination Tasks" in the Administration Console Online Help.

WebLogic JMS also takes advantage of the migration framework implemented in the WebLogic Server core for clustered environments. This allows WebLogic JMS to properly respond to migration requests and bring a JMS server online and offline in an orderly fashion. This includes both scheduled migrations as well as migrations in response to a WebLogic Server failure. For more information, see "Configuring JMS Migratable Targets" in the Programming WebLogic JMS.

You can also refer to the "WebLogic JMS Performance Guide" white paper (WeblogicJMSPerformanceGuide.zip) on the JMS topic page for more information.


Q. How can I control on which WebLogic Server(s) my application will run?

A. A system administrator can specify on which WebLogic Server(s) applications will run by specifying targets when configuring connection factories. Each connection factory can be deployed on multiple WebLogic servers. For more information on configuring connection factories or using the default connection factories, see "WebLogic JMS Fundamentals" in the Programming WebLogic JMS.


Q. How do I perform a manual fail-over?

A. The procedures for recovering from a WebLogic Server failure, and performing a manual failover, including programming considerations, are described in "Recovering From a WebLogic Server Failure" in Programming WebLogic JMS.


Q. Does the WebLogic JMS server find out about closed or lost connections, crashes, and other problems and does it recover from them?

A. Yes, but how it does this depends on whether a Java client crashes or WebLogic Server crashes, as follows:


Q. How does an application know if an application server goes down?

A. There are two exception listeners that you can register. Sun Microsystems' JMS specification defines Connection.setExceptionListener that tells you if there is a problem with the connection. That means that all consumers under that connection are also in trouble. The reason you will get the connection exception is because the WebLogic server you connect to on the other side is dead or not responding or someone killed your connection via the Mbean interface.

However, for WebLogic Server JMS, you may have multiple sessions in a connection, with the sessions going to multiple backend servers. WebLogic Server has an extension for this called WLSession.setExceptionListener that tells you if there is a problem with a session. For more information, see the JMS WLSession Javadoc.


Q. Do I need to use the WLS T3 protocol?

A. J2EE is all about making the interfaces standard. WebLogic's implementation of the RMI specification uses a proprietary wire-protocol known as T3. Sun's reference implementation of RMI uses a proprietary protocol called JRMP. The fact is that WebLogic developed T3 because they needed a scalable, efficient protocol for building enterprise-class distributed object systems with Java.

While T3 is specific to WebLogic, your application code does not need to know anything about T3 so you should not worry about this. Externalize the "WebLogic-specific strings" (PROVIDER_URL, INITIAL_CONTEXT_FACTORY, etc.) to a properties file (or somewhere) and you can make your code completely portable to where you only need change these in the properties file to get your code to run on another J2EE application server.

Note: As of release 8.1, WebLogic JMS also supports the IIOP protocol. In general, this is slower than the T3 protocol.


Q. How do I use HTTP tunneling?

A. If you want to use HTTP tunneling (wrap every message in HTTP to get through a firewall), you need to add TunnelingEnabled="true" into your <Server> definition in the config.xml file or check the appropriate box on the console. Then use a URL like http://localhost:7001 instead of t3://localhost:7001 for Context.PROVIDER_URL when getting your InitialContext. If you want HTTP tunneling with SSL, use https://localhost:7002 (where https uses HTTP tunneling with SSL and 7002 is the secure port that you configured). You will pay a performance penalty for doing this, so only use tunneling it if you really need to (i.e., need to go through a firewall).


Q. Does WebLogic JMS support SSL?

A. Yes, SSL is supported in the WebLogic JMS implementation. It is automatically used based on using a URL starting with "t3s:" instead of "t3:" when looking up the initial JNDI context.


Q. How do I integrate non-WebLogic JMS providers with WLS?

A. Refer to "Simple Access to Remote or Foreign JMS Providers" in the Administration Console Online Help and the "Using Foreign JMS Providers with WebLogic Server" white paper (jmsproviders.pdf) on the JMS topic page, for a discussion on integrating MQ Series, IBus MessageServer, Fiorano, and SonicMQ.


Q. How do two-phase or global transactions relate to WebLogic JMS?

A. A two-phase or global transaction allows multiple resource managers (including EJBs, databases, and JMS servers) to participate in a single transaction.

For example, a client can use a two-phase transaction to send a message from a queue on one JMS server (server A) to a queue on another JMS server (server B). Each server has a unique persistent store. When the transaction is committed, the message is made visible on server B. If the transaction rolls back, the message is put back on the queue on server A.

Note: If both queues happen to be on the same JMS server, then a one-phase transaction is used.


Q. Why is my WebLogic JMS work not part of a user transaction (that is, called within a transaction but not rolled back appropriately)? How do I track down transaction problems?

A. Usually this problem is caused by explicitly using a transacted session which ignores the external, global transaction by design (a JMS specification requirement). A transacted JMS session always has its own inner transaction. It is not affected by any transaction context that the caller may have.

It may also be caused by using a connection factory that is configured with the XAConnectionFactoryEnabled flag set to false.

  1. You can check if the current thread is in a transaction by adding these two import lines:
  2. import javax.transaction.*
    import weblogic.transaction.*;

    and adding the following lines (i.e., just after the begin and just before every operation).

    Transaction tran = TxHelper.getTransaction();
    System.out.println(tran);
    System.out.println(TxHelper.status2String(tran.getStatus()));

    This should give a clear idea of when new transactions are starting and when infection is occurring.

  3. Ensure that the thread sending the JMS message is infected with a transaction. Check that the code is not using a transacted session by setting the first parameter of createQueueSession or createTopicSession to false. Note that creating the connection and/or session is orthogonal to the transaction. You can begin your transaction before or after. You need only start the transaction before you send or receive messages.
  4. Check that the XAConnectionFactoryEnabled flag is explicitly set to true for the connection factory in the config.xml file since the default for user-configured connection factories for this value is false. If you are using one of the pre-configured connection factories they are set as follows:
  5. weblogic.jms.ConnectionFactory disables user transactions so don't use this one for the case where user transactions are desired;

    javax.jms.QueueConnectionFactory and javax.jms.TopicConnectionFactory enable user transactions.
  6. You can trace JTA operations by starting the server with this additional property:
  7. -Dweblogic.Debug.DebugJMSXA=true

    You should see trace statements like these in the log:

    XA ! XA(3163720,487900) <RM-isTransactional() ret=true>

    This can be used to ensure that JMS is infected with the transaction.


Q. When do WebLogic JMS operations take place as part of a transaction context?

A. When WebLogic JMS is used inside the server, JMS sessions may automatically be enlisted in the JTA transaction depending on the setting of various parameters. Prior to release 8.1, WebLogic JMS sessions would automatically be enlisted in the JTA transaction if either of the following two conditions were met:

In WebLogic Server 8.1, it is only necessary to set the XAConnectionFactoryEnabled flag. The old flags are still supported for backward compatibility, however.

When a WebLogic JMS connection factory is registered as a resource-reference inside an EJB, servlet, or JSP, and the connection factory is looked up out of the java:comp/env JNDI tree, then the EJB container checks to make sure that the appropriate flags are set for transaction enlistment. If the WebLogic JMS connection factory does not support automatic transaction enlistment, then the EJB container will throw an exception if a JMS session is used inside a transaction context. When used without a resource-reference however, such as in the case of an EJB that looks up a JMS connection factory directly, without using java:comp/env, then no checking takes place. If the JMS session is used outside a JTA transaction, then no enlistment takes place.

The default connection factory, weblogic.jms.ConnectionFactory, does not support automatic transaction enlistment. If you desire this behavior, you must use the weblogic.jms.XAConnectionFactory factory. (The legacy connection factories javax.jms.QueueConnectionFactory and javax.jms.TopicConnectionFactory support automatic transaction enlistment as well.)

For more information, see "Using JMS With EJBs and Servlets" in Programming WebLogic JMS.


Q. How can an application do a JMS operation and have it succeed, independent of the result of the transaction?

A. In order to do this properly, you must suspend the transaction. How you do this depends on the context in which you are using JMS:

  1. Inside an Enterprise Java Bean, there is no way to do this using only standard J2EE APIs. The most standards compliant way to do this is by invoking another EJB method (through the EJB container) that has container-managed transactions enabled and a transaction mode of NotSupported. This way, the EJB container will suspend the transaction before making the call, and resume it when the call has completed.
  2. You may also do this by accessing the WebLogic transaction manager. This method may be used inside an EJB or another server-side component such as a servlet. This requires using a WebLogic-proprietary interface, but you may find it to be more convenient. Here is an example:
  3. import javax.transaction.TransactionManager;
    TransactionManager tranManager= TxHelper.getTransactionManager();
    Transaction saveTx = null;
    try {
    saveTx = tranManager.suspend();
    ... do JMS work, it will not participate in transaction
    } finally {
    // must always resume suspended transactions!
    if (saveTx != null) tranManager.resume(saveTx);
    }
  4. Outside an EJB, you have other options. One is to use a transacted session. A transacted JMS session always has its own inner transaction. It is not affected by any transaction context that the caller may have. (However, if you use the deprecated WebLogic Server 5.1 default javax.jms.QueueConnectionFactory or javax.jms.TopicConnectionFactory factories, or if you define your own factory and set the UserTransactionsEnabled flag to True, the JMS session participates in the outer transaction, if one exists and the JMS session is not transacted.)
  5. Finally, you may use a WebLogic JMS Connection factory that does not support automatic transaction enlistment. For more information, see the previous question, When do WebLogic JMS operations take place as part of a transaction context?.

Q. What happens if acknowledge() is called within a transaction?

A. As per Sun Microsystems' JMS specification, when you are in a transaction, the acknowledgeMode is ignored. If acknowledge() is called within a transaction, it is ignored.


Q. Why am I getting JDBC XA errors when using JMS in conjunction with JDBC calls?

A. Whenever two resources (such as JMS and a database) participate in a transaction, the transaction becomes two-phase. The database driver you are using is not XA compatible and can't normally participate in a two-phase transaction. The solution is to either use an XA compatible driver, or to configure the JDBCTxDataSource value to set enableTwoPhaseCommit to true. The caveat for the latter is that this can lead to heuristic errors. If you don't want JMS to participate in the current transaction, see the question How can an application do a JMS operation and have it succeed, independent of the result of the transaction?.


Q. Can I use a one-phase commit if my WebLogic JMS JDBC store is on the same database for which I am doing other database work?

A. No. WebLogic JMS is its own resource manager. That is JMS itself implements XAResource and handles the transactions without depending on the database (even when the messages are stored in the database). That means whenever you are using JMS and a database (even if it is the same database as the JMS messages are stored) then it is 2PC.

You may find it will aid performance if you ensure the connection pool used for the database work exists on the same server as the JMS queue—the transaction will still be two-phase, but it will be handled with less network overhead. Another performance boost might be achieved by using JMS file stores rather than JMS JDBC stores.


Q. How do I integrate another vendor's XAResource with WLS to get JTA transactions with another resource manager?

A. In most cases WebLogic JMS will do this for you. For more information, see the "Using Foreign JMS Providers With WebLogic Server" white paper (jmsproviders.pdf) on the JMS topic page.


Q. Why do I get an exception when I start up WebLogic JMS using an XA driver or with a TX data source?

A. You cannot use a TX data source with JMS. JMS must use a JDBC connection pool that uses a non-XA resource driver (you can't use an XA driver or a JTS driver). Do not set the enableTwoPhaseCommit option. JMS does the XA support above the JDBC driver.


Q. Is WL JMS XAResource compliant?

A. Yes. WebLogic Server 6.1 or later fully implements the XAConnection, XAConnectionFactory, XAQueueConnection, XAQueueConnectionFactory, XAQueueSession, XASession, XATopicConnection, XATopicConnectionFactory, and XATopicSession methods. These methods are defined as optional in Sun Microsystems' JMS specification and are not part of the XAResource interface.

Note: These interfaces are not needed since WebLogic JMS automatically registers itself with the WebLogic transaction monitor.


Q. Why can't I receive a response to a message that I send within a transaction?

A. If you are using container-managed transactions, the original message sent from the EJB will never be sent. Here is what is happening.

  1. Container starts transaction.
  2. Start method.
  3. Generate new message.
  4. Send message (message isn't sent - it's buffered until transaction commit).
  5. Do a blocking receive on a queue.
  6. End method.
  7. Transaction Commit never Reached because original message was never sent because you can't get past blocking receive.

The solution is to either use bean-managed transactions, or to break the send and receive into two separate methods.


Q. What happens to a message that is rolled back or recovered?

A. For more information about what occurs when a message is rolled back or recovered, refer to "Managing Rolled Back, Recovered, Redelivered, or Expired Messages" in Programming WebLogic JMS.


Q. Is it possible to set aside a message and acknowledge it later?

A. There are no special primitives for doing this. Here are two possible solutions.

One approach is to use multiple sessions as in the following:

while (true) {
Create a session, subscribe to one message on durable subscription
Save session reference in memory
To acknowledge the message, find the session reference and call
acknowledge() on it.
}

Another solution is to use transactions and suspend the work as follows:

start transaction
while(true) {
message = receive();
if (message is one that I can handle)
process the message
commit
} else {
suspend transaction
put transaction aside with message
start transaction
}
}

To "acknowledge" the message:

resume user transaction
commit

To "recover" the message:

resume user transaction
rollback

Each time you suspend, you need to push the transaction onto a stack or list possibly with the message so you can process it or roll it back later. This solution is high overhead in that there can be a large build up of outstanding transactions. Note that transactions have timeouts and it may rollback on its own, which means you can get the message again (in a different transaction). Note also that there are some practical limits on the number of transactions you should leave outstanding. The default limit is something like 10000. Eventually you want to go back to your stack/list and commit/rollback the transactions. Note that transaction references (javax.transaction.Transaction) are not Serializable.


Q. How should I use sorted queues or topics?

A. Destinations are sorted as FIFO (first-in, first-out) by default; therefore, destination keys are used to define an alternate sort order for a specific destination. Destination keys can be message header or property fields. For a list of valid message header and property fields, refer to the "Message" section in Programming WebLogic JMS.

Destinations can be sorted in ascending or descending order based on the destination key. A destination is considered to be FIFO if a destination key is defined as ascending for the JMSMessageID message header field, and LIFO (last-in, first-out) if defined as descending. The key defined for the JMSMessageID header field, if specified, must be the last key defined in the list of keys. You can define multiple destination keys to sort a destination.

To create a destination key, use the Destination Keys node in the Administration Console. For more information, refer to "Destination Key Tasks" in the Administration Console Online Help.


Q. How do I deal with a listener that doesn't keep up with messages being sent?

A. Consider using the asynchronous pipeline for your message listeners to improve performance, as described in the "Asynchronous Message Pipeline" section of Programming WebLogic JMS.


Q. How do I get a thread dump to help track down a problem?

A. Ways to get a thread dump:


Q. Do client identifiers need to be unique?

A. Yes, durable subscribers require unique client identifiers. For more information on configuring durable subscribers using the connection factory's Client ID attribute, or by programming your application to set a client ID in its connection (by calling the setClientID() connection method), see "Setting Up Durable Subscribers" in Programming WebLogic JMS.


Q. How do I manage a queue to view and delete specific messages?

A. Write a program that uses a QueueBrowser. Then delete specific messages by using a QueueReceiver with a selector with the message identifier, as shown in the following example:

String selector = "JMSMessageID = '" + message.getMessageID() + "'";

Keep in mind that the queue browser is a not a "live" view of the queue. It is a snap-shot.


Q. In what order are messages delivered to a consumer?

A. Order is maintained between any producer and consumer for like delivery mode, sort order, and selector in the absence of a rollback or recover. There are no guarantees of order when multiple producers send to a single consumer or multiple consumers receive from multiple producers.

Order is generally maintained between a producer and a consumer. However, non-persistent messages can get ahead of persistent messages of a higher sort order (i.e., higher priority), can move ahead of each other and a recover or rollback puts messages that were already received back into the queue/topic, which affects order.

Most messaging systems (including WebLogic JMS) maintain order between a producer and a destination and then order between the destination and the consumer. So, once things arrive at the destination, the order does not change.

Finally, the asynchronous pipeline that is supported in WebLogic JMS affects the ordering. By default there can be as many as ten outstanding messages pushed out from the server to an asynchronous client that have not been seen by the client yet. If the asynchronous consumer is "caught" up, these messages will not be sorted. Destination sorting does not occur in the pipeline. If a destination is sorted by priority, and a new message comes in of higher priority than those messages already in the pipeline, it will not leap ahead in the pipeline, it will become first in the destination. The size of the pipeline is configurable; see the MessagesMaximum setting on the connection factory used. If you want real priority sorting, change the maximum number of messages on the factory to one. For more information, see the "Asynchronous Message Pipeline" section of Programming WebLogic JMS.


Q. How do I ensure message ordering even in the event of rollbacks and recoveries?

A. In WebLogic JMS 8.1 message ordering can be maintained to single consumers on a queue or topic subscription - even in the event of rollbacks and recoveries, as described in "Ordered Redelivery of Messages" in Programming WebLogic JMS.


Q. Is it possible to have multiple queue receivers listening on the same queue?

A. Yes, although the JMS specification does not define the behavior here.


Q. Is there a way to make a queue such that if one application has one object as listener on that queue, no other application can listen to the messages on that queue?

A. No. An alternative is to create a topic with a single durable subscription because a durable subscription may only have one consumer associated with it. The only drawback is that selectors would no longer work the same as they do with queues. Changing the selector on a durable subscription "resets" the subscription as per Sun Microsystems' JMS specification, causing all messages currently in the subscription to be deleted.

Note: If you configure a connection factory that has its Client ID set, this limits the connection factory to one client and may serve the purpose.


Q. Why doesn't setting values work using javax.jms.Message.setJMSPriority, DeliveryMode, Destination, TimeStamp or Expiration?

A. These methods are for vendor use only. The message values are overwritten on each send/publish. You should use the equivalent methods on the MessageProducer, QueueSender, or TopicPublisher to set these values (i.e., setJMSPriority, setDeliveryMode, setTimeToLive). Check to see that these values are not being overridden by the optional template configuration override values.


Q. What care must be taken when multi-threading WebLogic JMS clients?

A. The rules for multi-threading are described in section 2.8 of the JMS specification, with additional language in sections 4.4.6 on session usage, 4.4.9 on using multiple sessions, and 4.4.17 on concurrent message delivery. In a nutshell, it states that JMS sessions are single-threaded. Consequently, if multiple threads simultaneously access a session or one of its consumers or producers the resulting behavior is undefined. In addition, if multiple asynchronous consumers exist on a session, messages will be delivered to them in series and not in parallel.

To take advantage of multiple threads with JMS, use multiple sessions. For example, to allow parallel synchronous receive requests, design the application so that only one consumer may be active per session and use multiple sessions.


Q. How should an application be set up to subscribe to multiple topics?

A. If you want to listen to N topics, using N subscribers and N sessions gives you concurrency up to N simultaneous threads of execution provided you have that many threads to work with. N subscribers and 1 session serializes all subscribers through that one session. If the load is heavy they may not be able to keep up without the extra threads. Also, if you are using CLIENT_ACKNOWLEDGE, N sessions gives you N separate message streams that can be individually recovered. Having 1 session crosses the streams giving you less control.

As of version 6.x or later, WebLogic JMS on the server side efficiently uses a small, fixed number of threads independent of how many client sessions there are.


Q. How should I use blocking and asynchronous receive() calls?

A. The synchronous receive() method blocks until a message is produced, the timeout value, if specified, elapses or the application is closed. We strongly recommend that you avoid using blocking receive() calls on the server side because a synchronous receive() call consumes resources for the entire duration that the call is blocked.

When methods are received asynchronously, the application is notified using a message listener only when a message has been produced, so no resources are consumed waiting for a message.


Q. What precautions should I take when I use blocking receive() calls?

A. If your application design requires messages to be received synchronously, we recommend using one of the following methods listed in order of preference:

Note: Use of this option should be minimized, as it may deadlock a busy server.


Q. What is the NO_ACKNOWLEDGE acknowledge mode used for?

A. The NO_ACKNOWLEDGE acknowledge mode indicates that received messages do not need to be specifically acknowledged which improves performance, but risks that messages are lost. This mode is supported for applications that do not require the quality of service provided by session acknowledge and that do not want to incur the associated overhead.

Messages sent to a NO_ACKNOWLEDGE session are immediately deleted from the server. Messages received in this mode are not recovered and, as a result, messages may be lost and/or duplicate message may be delivered if an initial attempt to deliver a message fails.

Note: You should avoid using this mode if your application cannot handle lost or duplicate messages. Duplicate messages may be sent if an initial attempt to deliver a message fails.

In addition, we do not recommend that this acknowledge mode be used with persistent messaging, as it implies a quality of service that may be too low for persistent messaging to be useful.


Q. When should I use multicast subscribers?

A. Multicasting enables the delivery of messages to a select group of hosts that subsequently forwards the messages to multicast subscribers. The benefits of multicasting include:

Note: Multicasting is only supported for the Pub/sub messaging model.

For an example of when multicasting might be useful, consider a stock ticker. When accessing stock quotes, timely delivery is more important than reliability. When accessing the stock information in real-time, if all, or a portion, of the contents is not delivered, the client can simply request the information be resent. Clients would not want to have the information recovered in this case because by the time it is redelivered it would be out-of-date.

Multicast messages are not guaranteed to be delivered to all members of the host group. For messages requiring reliable delivery and recovery, you should not use multicasting.


Q. When should I use server session pools and connection consumers?

A. WebLogic JMS implements an optional JMS facility for defining a server-managed pool of server sessions. However, session pools are now used rarely, as they are not a required part of the J2EE specification, do not support JTA user transactions, and are largely superseded by message-driven beans (MDBs), which are simpler, easier to manage, and more capable.

For a detailed discussion on this topic, see the "MDBs vs. ServerSessionPools" section in the "WebLogic JMS Performance Guide" white paper (WeblogicJMSPerformanceGuide.zip) on the JMS topic page.


Q. How do I issue the close() method within an onMessage() method call and what are the semantics of the close() method?

A. If you wish to issue the close() method within an onMessage() method call, the system administrator must select the Allow Close In OnMessage check box when configuring the connection factory. For more information, see "JMS Connection Factory Tasks" in the Administration Console Online Help. If this check box is not selected and you issue the close() method within an onMessage() method call, the call will hang.

The session or connection close() method performs the following steps to execute an orderly shutdown:

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.

When you close a session, all associated producers and consumers are also closed.

For more information about the impact of the close() method for each object, see the appropriate javax.jms javadoc.


Q. How do I publish an XML message?

A. Follow these steps:

  1. Generate XML from the DOM document tree.
  2. Serialize the generated DOM document to a StringWriter.
  3. Call toString on the StringWriter and pass it into message.setText.
  4. Publish the message.

Q. How do I use WebLogic JMS in an applet?

A. For detailed instructions and examples on how to accomplish this, see "Using BEA WebLogic JMS with Applets" on BEA's JMS topic page.


Q. How do I use a startup class to initialize and later reference WebLogic JMS objects?

A. This topic is covered in news://newsgroups.bea.com/3ad0d7f3@newsgroups.bea.com. The sample code does not cleanup properly at shutdown. You can use a shutdown class that does something like the following:

JMSobject WLSobject = null;
try {
WLSobject = JMSStartUp.getJMSobject();
WLSobject.JMSCleanup();
} catch(Exception e) {}

Load-on-start servlets can provide a nice solution to provide both initialization and cleanup. For more information, refer to What is the standard way to create threads, do initialization, etc. within the application server?.


Q. Is it possible to send or receive a message from within a message listener?

A. Yes. You can send to or receive from any queue or topic from within in a message listener.

Outside of a MDB, you can do this by using the same Connection or Session that the onMessage() is part of. When you create your message listener, you pass a session into your constructor. Then you have access to the session in your onMessage() method and are able to make synchronous - not asynchronous - calls from within the onMessage() method. Do not use another Session that is servicing another onMessage(), because that would multi-thread the Session, and Sessions do not support multi-threading.

However, when using this technique outside a MDB, there is no way to guarantee that the receipt of the message by the MessageListener, and the send of the new message, happen as part of the same transaction. So, there can be duplicates or even lost messages. For example:

If you require exactly-once transactional semantics using onMessage(), then you must use transactional MDBs. In this case, the onMessage() method for a transactional MDB starts the transaction and includes the WebLogic JMS message received within that transaction. Then, you must ensure that the send or publish of the new message is part of the same transaction as the receipt of the message.

In WebLogic Server 8.1, you can guarantee that this happens by using a connection factory that you get from a resource-reference defined for the MDB. For detail instructions on how to accomplish this, see "Using JMS With EJBs and Servlets" in Programming WebLogic JMS. By using a resource-reference, you also get automatic pooling of the JMS Connection, Session, and MessageProducer objects, and the transaction enlistment will happen automatically regardless of whether you use WebLogic JMS or another JMS provider, as long as the JMS provider supports XA.

In earlier versions of the product, WebLogic JMS would automatically enlist itself with the current transaction if the UserTransactionsEnabled or XAServerEnabled flag was set on the connection factory. However, prior to release 8.1, the server will not pool any JMS objects or automatically enlist a foreign JMS provider in the transaction. In these earlier versions, you may want to cache JMS objects yourself. For more information, see How do I create a producer pool?.


Q. How do I create a producer pool?

A. For instructions on how to accomplish this, see "Using JMS With EJBs and Servlets" in Programming WebLogic JMS. For a detailed code sample, see the "Appendix A: Producer Pool Example" section in the "WebLogic JMS Performance Guide" white paper (WeblogicJMSPerformanceGuide.zip) on the JMS topic page.


Q. What are pending messages in the console?

A. Pending means the message could have been:

A rolled back message remains pending until the transaction actually rolls back. Rolling it back multiple times does not cause double counting, nor does an exception that set a transaction as rollbackOnly followed by an actual rollback.

Current implies messages that are not pending.

Total implies total since server last started. The byte counts only consider the payload of messages which includes the properties and the body but not the header.


Q. How do I use a less than or greater than on a message selector in ejb-jar.xml?

A. Enclose the selector in a CDATA section. That will prevent the XML parser from thinking that less than or greater than is a tag.

<jms-message-selector>
<![CDATA[ JMSXAppID <> 'user' ]]>
</jms-message-selector>

Q. Can I use another vendor's destination with a WebLogic JMS API?

A. WebLogic Server JMS does not know what to do with foreign destinations that it runs into. This issue has been discussed with Sun and the specification does not clearly define destinations well enough for vendors to interoperate at that level. They agree that it is sufficient not to handle foreign destinations preferably in such a way that sending/receiving still work. For WebLogic JMS, if you do a setJMSdestination (you should not because it is only for the provider to set it) with a foreign destination, it gets ignored (set to null). Similarly, if you do a setJMSReplyTo for a foreign destination, WebLogic JMS will ignore it (set it to null).


Q. What is the standard way to create threads, do initialization, etc. within the application server?

A. Threads should generally not be created by the user directly is because things may not work correctly. User-created threads do not have some of the thread-local variables pre-set by WebLogic when it creates it's own execute threads, the associated transaction context, or the environment such as the proper class loader. The WebLogic-specific way of doing this is with a startup class or using the WebLogic Time Services. The portable way to do this is to define a load-on-startup servlet, doing the initialization in the init() method and the cleanup in the destroy() method. The servlet itself does nothing. This approach also allows for undeploy/redeploy of the application without restarting the server, including proper cleanup/initialization each time. It also providers more dynamic management of the dependent classes without restarting the server.


Q. Why do I get a JNDI problem when I name a Topic A.B and a second Topic A.B.C?

A. This is a JNDI implementation issue. JNDI uses the dots to build a directory-like structure. A given element cannot be both a node and a leaf in the tree. In this example, B is used as a leaf off of A, but then is used as a node off of which C is a leaf.


Q. What should an XPATH selector look like?

A. For instructions and samples about using XPATH syntax with WebLogic JMS, see "Defining XML Message Selectors Using the XML Selector Method" in Programming WebLogic JMS.


Q. How do I handle request/response using WebLogic JMS?

A. There are several approaches to handling request/response processing with JMS.


Q. Is it okay to add new sessions and subscribers to a Queue or Topic Connection once it has been started?

A. Yes, with one caveat. You may not add new subscribers/consumers to a session if it already has active async consumers. Sessions must only be accessed single-threaded as per the JMS Specification. If you feel you need to do this, create a new Session and add it to that one instead.

You can add receivers to a session that is part of a started connection. However, a receiver in itself is not asynchronous. You need a listener to make it asynchronous. The first creation of a receiver is always safe. If you then add a listener for that first receiver, you have to worry for any future receivers in that same session. You can create new sessions and the first receiver for that session with no worries.

Once you want to create a second receiver in a session, if the first receiver has a MessageListener, you have to take care to make sure there are no other threads of execution in that session. You can do this by stopping the connection or actually creating your receiver from the onMessage routine of the first receiver.


Q. What can I do when I get java.lang.OutOfMemoryError because producers are faster than consumers?

A. Quotas can be used to help this situation. Your sender will then receive ResourceAllocationExceptions and the server will stay up. In release 8.1 or later, senders can be configured to block waiting for space rather than receive ResourceAllocationExceptions. For more information, see "Avoiding Quota Exceptions by Blocking Message Producers" in the Administration Console Online Help.

You can also use the Message Paging feature, which saves memory by swapping messages out from virtual memory to a dedicate paging store when message loads reach a specified threshold. JMS message paging saves memory for both persistent and non-persistent messages, as even persistent messages cache their data in memory. For more information, see "Paging Out Messages To Free Up Memory" in the Administration Console Online Help.


Q. How should connections and sessions be allocated?

A. Think of a connection as a single physical connection (a TCP/IP link). A session is a means for producing and consuming an ordered set of messages. Creating a connection is generally expensive. Creating a session is less expensive. Generally people use one connection and share across all the threads with each thread having its own session. If you have thread groups and need to start/stop/close the resources for a given group, one connection per group is good. A group can have exactly one thread.


Q. Is there a way to dynamically change an existing selector for a TopicConsumer using the setMessageSelecter(String)?

A. No. Once you instantiate the consumer the selector is fixed at the time that the consumer is created. Changing the selector is like removing the current consumer, removing all associated messages and then creating a new one.


Q. How can I avoid asynchronous message deadlocks?

A. Due to a limitation in the JMS specification, asynchronous messages can become deadlocked if the close() method of a session is inside a user-synchronized block. To resolve this, you must move the close() method outside the user-synchronized block. For example:

public class CloseTest() {
private void xxx() {
synchronized (this) {
create connection/session/consumer
initialize and set a listener for this consumer;
wait();
connection.close();
}
}
 private void onMessage(Message message) {
synchronized (this) {
notify();
}
}
}

Before the connection.close() method is closed, another message can be delivered to the onMessage routine by the JMSProvider. The main() method thread owns the monitor lock for the CloseTest method. Before the onMessage() method of the CloseTest class fires, JMS sets INLISTENER as the state for the session in JMSSession (the JMS specification says that the close() method must wait for the onMessage routine), so that the main() method thread can wait for the onMessage routine to complete.

Now when the onMessage routine tries to acquire the monitor lock, it blocks waiting for the main() method thread to give up, and the main() method thread is waiting for the onMessage to be completed.

JMS also blocks when the close() method of a consumer is done from an onMessage routine and the allowCloseInOnMessage attribute is set to false in the config.xml file.


Q. What are the advantages of message-driven beans?

A. The message-driven bean is a stateless component that is invoked by the EJB container as a result of receiving messages from a JMS queue or topic. It then performs business logic based on the message contents, effectually freeing you from any JMS configuration and reconnection chores.

The message-driven bean model allows EJB developers to work with a familiar framework and set of tools, and also provides access to the additional support provided by the container. The goal of the message-driven bean model is to assure that developing an EJB that is asynchronously invoked to handle the processing of incoming JMS messages is as easy as developing the same functionality in any other JMS MessageListener.

One of the main advantages of using message-driven beans in place of the standard JMS MessageListener is that a JTA transaction can be started for you automatically and the received message will be part of that transaction. In this case, other operations can be infected with the same JTA transaction such as database operations. This is the only way to infect a message from an asynchronous consumer and another JTA operation with the same transaction.

For more information on message-driven beans, see "Designing Message-Driven Beans" in Programming WebLogic Enterprise JavaBeans.


Q. How does concurrency work for message-driven beans?

A. For a queue, multiple JMS Sessions are created on each server instance where the MDB is deployed. The number of sessions created is never greater than the max-beans-in-free-pool setting in the MDB's deployment descriptor. JMS then delivers messages in parallel to the MDB instances as it would for any other kind of message listener. If a MDB is deployed to multiple servers in a cluster, Sessions are created for each MDB instance on each server.

For a topic, however, one topic consumer is used to pass out messages to multiple threads to get concurrency, while producing only a single copy of each message. If multiple MDBs are deployed to listen on the same topic, then each MDB will receive a copy of every message. Therefore, when a MDB is deployed to multiple servers and it listens to a topic, each server will receive its own copy of each message. So, if you want a message to be processed by exactly one MDB, you should use a queue.


Q. Can an MDB be a message producer or both a producer and consumer?

A. Yes. You have no JMS context inside the MDB so you will need to establish a connection, session and producer yourself. One option is to do this every time you come into the onMessage routine for the MDB. This is sufficient if the message rate is relatively low. The second option is to establish the necessary objects in ejbActivate(). Note that the objects are not serializable so they can't be passivated for a stateful session bean or an entity bean. When the EJB deactivates, you need to close the associated objects. The third option is that you could build up a JMS connection/sender session pool within a startup class complete with your own synchronization and blocking to get a connection. There is an example of this in the question Is it possible to send or receive a message from within a message listener?.

For more information, see "Using JMS With EJBs and Servlets" in Programming WebLogic JMS.


Q. If an MDB uses a durable subscription, will messages be accumulated if the MDB is not deployed?

A. The durable subscription is created when the MDB is deployed for the first time. The durable subscription is not deleted when the MDB is undeployed or deleted. This means that once the MDB has been deployed once, messages will continue to accumulate on the subscription, even if the MDB is undeployed or deleted. So, when an MDB is retired from service, you should delete the durable subscription to prevent a build-up of messages. You can use the administration console to do this, or you can write a standalone program using the Java API that calls unsubscribe on the durable subscription.


Q. How do I use non-WebLogic JMS provider destinations to drive MDBs?

A. See the "Using Foreign JMS Providers with WebLogic Server" white paper (jmsproviders.pdf) on the JMS topic page.


Q. Can you use a foreign JMS provider to drive an MDB transactionally?

A. Yes. In WebLogic Server 7.0 or later, you can deploy an MDB that supports container-managed transactions against a foreign JMS provider. If the MDB is configured with a "transaction-type" attribute of "Container" and a "trans-attribute" of "Required", then WLS will use XA to automatically enlist the foreign JMS provider in a transaction. (See the next question for an example of an MDB that uses container-managed transactions.)

If the foreign JMS provider does not support XA, then you cannot deploy an MDB that supports container-managed transactions with that provider. Furthermore, if the JMS provider does support XA, you must ensure that the JMS connection factory that you specify in the weblogic-ejb-jar.xml file supports XA—each JMS provider has a different way to specify this.

See the "Using Foreign JMS Providers with WebLogic Server" white paper (jmsproviders.pdf) on the JMS topic page for an example of how to configure an MDB to use a foreign provider.


Q. How do I roll back a transaction within an MDB?

A. To roll back a transaction, you can either use the Weblogic extension TXHelper, or you can use the MDB context as in the following code examples:

UserTransaction ut =
weblogic.transaction.TXHelper.getUserTransaction();
ut.setRollbackOnly();

or

private MessageDrivenContext context;
public void setMessageDrivenContext(
MessageDrivenContext mycontext) {
context = mycontext;
}
public void onMessage(Message msg) {
try { // some logic
}
catch(Exception e) {
System.out.println("MDB doing rollback");
context.setRollbackOnly();
}

Q. How do server session pools and message driven beans compare?

A. For a detailed discussion on this topic, see the "MDBs vs. ServerSessionPools" section in the "WebLogic JMS Performance Guide" white paper (WeblogicJMSPerformanceGuide.zip) on the JMS topic page.

 

Skip navigation bar  Back to Top Previous Next