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:
The WebLogic JMS index page
Programming WebLogic JMS
“Configuring JMS” and “Tuning JMS” in the Administration Console Online Help
“The WebLogic Messaging Bridge” in the Administration Console Online Help
BEA’s dev2dev web site
Ask BEA
The WebLogic JMS “weblogic.developer.interest.jms” newsgroup available on the BEA
Newsgroup server.
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.
For instructions on developing a thin client, see “Developing a J2EE Application Client
(Thin Client)” in Programming WebLogic RMI over IIOP.
For information about the JMS jar, see “WebLogic JMS Thin Client” in Programming
WebLogic JMS.
For an overview of client options, see “Using RMI over IIOP Programming Models to
Develop Applications” in Programming WebLogic RMI over IIOP.
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?” on page 14-6 for a
description about how to configure JMS. The resulting template definition looks something like
the following:
The JMSServer is defined something like:
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
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
Store="
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).
2. Make sure you are not using "Message.setJMSDeliveryMode". This is overwritten, as it is a
vendor-only method.
3. Make sure you are calling either:
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.
4. Make sure you don't have "DeliveryModeOverride" set to Non-Persistent on the Destination
in the config.xml file.
5. 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?” on page 14-6 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?
1411
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
1412
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:
If a Java client crashes then the JMS server will clean up all the outstanding server-side
resource from the crashed client JVM, such as:
– JMS connection(s) from the crashed client JVM
– JMS temporary destination(s) created under the above JMS connection(s)
– JMS session(s) created under the above JMS connection(s)
– JMS client(s) created under the above JMS session(s) (connection consumer and
regular consumer)
– JMS browser(s) created under the above session(s)
– JMS producer(s) created under the above session(s)
If WebLogic Server crashes and it is the front-end to the JMS server, then:
– A JMS client will lose all the server-side resources listed above.
– The client’s javax.jms.ExceptionListener.onException(...) will be called (if
javax.jms.JMSConnection.setExceptionListener is set) with a
LostServerException, which extends JMSException.
If WebLogic server crashes and it is a back-end to the JMS server, then:
– A JMS client may partially lose some of the server-side resources listed above (only the
resource on the crashed server, such as JMS temporary destination(s), JMS client(s) and
JMS browser(s).
– The client’s javax.jms.ExceptionListener.onException(...) will be called (if
weblogic.jms.extensions.WLSession.setExceptionListener is set) with a
ConsumerClosedException, which extends JMSException.
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
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:
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.
2. 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.
3. 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:
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.
4. You can trace JTA operations by starting the server with this additional property:
-Dweblogic.Debug.DebugJMSXA=true
You should see trace statements like these in the log:
XA ! XA(3163720,487900)
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:
The XAConnectionFactoryEnabled and UserTransactionsEnabled flags were set on the
connection factory.
The XAServerEnabled flag was set on the connection factory.
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:
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);
}
3. 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.)
4. 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?” on page 14-15.
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?” on page 14-16.
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:
Try running this from the command line (after running the setEnv script in
WL_HOME\server\bin):
java weblogic.Admin -url t3://localhost:7001 THREAD_DUMP
On Windows, from the console window, enter Ctrl+Break.
On UNIX, signal the server using kill -3.
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:
Pass a timeout value as an argument to the receive() method and set it to the minimum
value greater than zero, that is allowed by the application to avoid consuming threads that
are waiting for a response from the server.
Use the receiveNoWait() method which returns the next message or a null value if no
message is currently available. In this case, the call does not block. The servlet should
provide a way to return to or reschedule the request, without calling wait().
Note: Use of this option should be minimized, as it may deadlock a busy server.
Ensure that more threads are configured than the number of possible simultaneous blocking
receive() calls.
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:
Near real-time delivery of messages to host group.
High scalability due to the reduction in the amount of resources required by the JMS server
to deliver messages to multicast subscribers.
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:
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
(except for the message listener from which the close() method is being called).
Rolls back in-process transactions on its transacted sessions (unless such transactions are
part of an external JTA user transaction).
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.
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?” on page 14-29.
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 call acknowledge after the publish() and the acknowledge fails for whatever
reason (network or server failure), then you will see the message again and will end up
publishing twice (possible duplicate semantics). You can try to keep track of sequence
numbers to detect duplicates, but this is not easy.
If you call acknowledge before the publish(), you get at-most-once transaction
semantics. If the publish() fails, you don’t know if the failure occurred before or after
the message reached the server.
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?” on page 14-28.
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:
sent in a transaction but not committed.
received and not acknowledged.
received and not committed.
subject to a redelivery delay (as of WebLogic JMS 6.1 or later).
subject to a delivery time (as of WebLogic JMS 6.1 or later).
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.
'user' ]]>
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
1429
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.
Use a temporary queue for each requestor and have the response go back to that queue.
Use the QueueRequestor class, which does the temporary queue for you, and wait for the
reply, as in the following:
// create temporary queue for receiving answer
qrequestor = new QueueRequestor(qsession, queue);
TextMessage msg = qsession.createTextMessage();
TextMessage reply = (TextMessage) qrequestor.request(msg);
Use a dedicated response topic or queue with message selectors.
For more information on request/response, see the “Using a Request/Response Design”
section in the “WebLogic JMS Performance Guide” white paper
(WeblogicJMSPerformanceGuide.zip) on the JMS topic page.
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?” on page 14-26.
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.
Q. Why did the messaging bridge fail to connect to the source bridge destination?
A. Either an error occurred when configuring the source bridge destination parameters, or the
actual source destination is not running and cannot communicate with the messaging bridge.
Verify whether the bridge’s source destination is correctly configured, by making sure that
the following fields on the JMS Bridge Destination → Configuration console page have
been properly completed:
– Connection URL—this must be the URL of the JNDI provider used to look up the
connection factory and actual destination.
– Destination JNDI Name—this must be the JNDI name of the actual destination mapped
to the source bridge destination.
– Connection Factory JNDI Name—this must be the connection factory used to create a
connection for the actual destination mapped to the source bridge destination.
– User Name/Password—make sure that this user ID has permission to access the actual
source destination.
Verify that the actual source queue or topic destination mapped to the source bridge
destination is running and healthy, as follows:
– Is the WebLogic Server instance hosting the source destination running?
– Is the JMS server hosting the source destination correctly deployed?
Note: This troubleshooting scenario for correcting a source bridge destination connection
failure also applies to target bridge destinations.
Q. Can the messaging bridge handle two-phase or global transactions between separate
WebLogic Server domains or between different releases?
A. Yes, as long as the communication is between source and target WebLogic domains that are
both running release 6.1 SP03 or later, and the bridge is configured to use the Exactly-once
quality of service.
For more information about using the Exactly-once QOS when interoperating between release
6.1 and release 7.0 domains and higher, see “Using the Messaging Bridge To Access Destinations
In a Release 6.1 or Later Domain” in the Console Help.
Q. I configured the messaging bridge to use the Exactly-once quality of service for two-phase
transactions. So why am I getting a “quality of service is unreachable” error?
A. There are some additional configuration requirements for the messaging bridge to handle
transactions between WebLogic domains:
The supported adapters are located in the WL_HOME\server\lib directory. For the
Exactly-once QOS, the transaction adapter, jms-xa-adp.rar, must be deployed in the
release 8.1 domain where the bridge is running, via the select Deployments → Connector
node on the console.
This jms-xa-adp.rar adapter must also be identified in the Adapter JNDI Name attribute
as eis.jms.WLSConnectionFactoryJNDIXA on the JMS Bridge Destination →
Configuration tab for both the source and target bridge destinations.
For WebLogic JMS, verify that you are using the transactional XAConnectionFactory for
the queue or topic destinations mapped to both the source and target bridge destinations. To
verify this, the following attributes must be set on the JMS → Connection Factory →
Configuration → Transactions console tab or in the configuration file (config.xml):
UserTransactionsEnabled=true
XAConnectionFactory=true
For third-party JMS vendors, verify that you are using a transactional connection factory
for the destinations mapped to the source and target bridge destinations.
For more information about using the Exactly-once QOS when interoperating between release
6.1 and release 7.0 or later domains, see “Using the Messaging Bridge To Access Destinations In
a Release 6.1 or Later Domain” in the Console Help.
Q. Can I configure the messaging bridge to automatically downgrade the quality of service if the
Exactly-once service isn’t available on either the source or target bridge destination?
A. Yes, just make sure to select the QOS Degradation Allowed check box on the Messaging
Bridge → Configuration → General administration console page.
Q. Why do I get a security authorization exception when attempting to forward messages from
a WebLogic Server 7.0 GA, SP01, or SP02 destination to a release 6.1 destination?
java.lang.SecurityException: Invalid Subject: principals=[user1]
A. In WebLogic Server 6.1, the trust relationship between two WebLogic Server domains was
established if the system password was the same in both domains. For a release 7.0 GA, SP01,
and SP02 messaging bridge to communicate with a release 6.1 domain, you must establish a
trusted relationship across release the 6.1 and 7.0 domains. A trusted relationship is established
when the Credential attribute for one domain matches the Credential attribute for another domain.
Therefore, if you want a release 6.1 domain to interoperate with a release 7.0 SP02 or earlier
domain, you need to change the Credential attribute in both domains to the password of the
“system” user in the release 6.1 domain.
However, for release 7.0 SP03 or later, you do not need to establish a trusted relationship across
release 6.1 and 7.0 domains.
For more information about establishing a trust relationship between release 7.0 and 6.1
domains for the messaging bridge, see “Enabling Security Interoperability for WebLogic
Domains” in Console Help.
For more information about release 6.1 domain interoperability security, see “Using
Compatibility Security” in Managing WebLogic Security.
For more information about WebLogic Server 7.0 domain interoperability security, see
“Enabling Trust Between WebLogic Domains” in Managing WebLogic Security.
Q. I deployed the transactional jms-xa-adp.rar resource adapter on the WebLogic 8.1 domain
where the message bridge is running, but I still get a “failed to find bridge adapter” message?
A. You need to associate both the source and target bridge destinations with the appropriate.rar
adapters in order for the bridge to communicate with them. For the jms-xa-adp.rar transaction
adapter, it must be identified in the Adapter JNDI Name attribute as
eis.jms.WLSConnectionFactoryJNDIXA on the JMS Bridge Destination → Configuration tab
for both the source and target bridge destinations.
Note: The “failed to find bridge adapter” message does not necessarily indicate a problem if it
only occurs once. However, if it occurs repeatedly, you should check the adapter
deployment and the adapter JNDI name used in the source and target bridge destinations.
For more information about the bridge resource adapters, see “About the Bridge’s Resource
Adapters” in the Console Help.
Q. When configuring a source or target messaging bridge destination, do I need to set the Adapter
Classpath field?
A. Leave the Adapter Classpath field blank when connecting to source and target destinations
that are both running on release 8.1. When connecting to either a source or target destination that
1539
is running on release 6.0 or earlier, the Adapter Classpath field must indicate the location of the
classes for the earlier WebLogic Server release. When connecting to a third-party JMS provider,
the bridge destination must supply the provider’s CLASSPATH in the WebLogic Server
CLASSPATH.
Q. Can the messaging bridge forward durable subscription messages between separate
WebLogic Server 6.1 and release 7.0 or later domains?
A. Yes, as long as the domain hosting the bridge is using WebLogic 7.0 Service Pack 1 or later.
To enable durable messages across the messaging bridge using the Administration Console,
select the Durability Enabled attribute on the
Q. How do I enable debugging for the messaging bridge?
A. You can enable debugging for the messaging bridge using either of the followings methods:
Add the following lines to your WebLogic start script (before the weblogic.Server
line):
-Dweblogic.Debug.DebugMessagingBridgeStartup=true
-Dweblogic.Debug.DebugMessagingBridgeRuntime=true
Add the following statements to the ServerDebug entry in your configuration file
(config.xml) for the server that the messaging bridge is running on:
DebugMessagingBridgeStartup="true"
DebugMessagingBridgeRuntime="true"
Once debugging is enabled for the messaging bridge, the debugging messages are sent to the
server log by default. However, if you want them to appear in the Administration Console, add
“DumpToConsole” to the statements show above. For example:
-Dweblogic.Debug.DebugMessagingBridgeStartupDumpToConsole=true
Q. What do the messaging bridge monitoring states indicate on the
console page?
1540
A. When monitoring a messaging bridge’s state, use the following table to determine a course
of action, if necessary. For more information, see Managing a
Help.
Table 15-1
Description Action
WARN: Failed to find the source
adapter
Check if the adapter is deployed or the JNDI name in
the source JMSBridgeDestination instance is correct.
WARN: Failed to find the target
adapter
Check if the adapter is deployed or the JNDI name in
the target JMSBridgeDestination instance is correct.
Found both of the adapters and
making connections
No.
WARN: Stopped by the administrator No.
WARN: Failed to look up the source
adapter
Check if the adapter is deployed or the JNDI name in
the source JMSBridgeDestination instance is correct.
WARN: Failed to look up the target
adapter
Check if the adapter is deployed or the JNDI name in
the target JMSBridgeDestination instance is correct.
Found two adapters and about to
make connections
No.
WARN: Failed to connect to the
source
Check all the parameters configured for the source
bridge destination.
Check if the source server is running and whether the
actual destination is active.
Connected to the source No.
WARN: Failed to connect to the
target
Check all the parameters configured for the target
bridge destination.
Check if the target server is running and whether the
actual destination is active.
Connected to the target No.
Forwarding messages No.
WARN: Failed to connect and will
reconnect later
Check if the source and target bridge destinations are
running and healthy.
1541
Q. Is there another way to monitor the messaging bridge without using the Administration
Console?
A. Yes, there is a run-time MBean (MessagingBridgeRuntimeMBean) for each bridge
instance. WebLogic Server run-time MBeans provide a snapshot of information about domain
resources. When a particular resource in the domain (such as a messaging bridge) is instantiated,
an MBean instance is created which collects information about that resource.
The MessagingBridgeRuntimeMBean has a getState() method that currently returns a String
(“Active” or “Inactive”) and a getDescription() method, which returns a String with more
detailed information. The name of a bridge runtime MBean consists of the WebLogic Server
instance name and the bridge name. If a bridge named mybridge, runs on WebLogic Server
instance named myserver, the bridge runtime MBean will be named myserver.bridge.mybridge.
For more information about using run-time Mbean management commands, see “WebLogic
Server Command-Line Interface Reference” in the Administration Guide. For more information
about programming MBean monitoring notifications, see “Using WebLogic Server MBean
Notifications and Monitors” in Programming WebLogic JMX Services.
Q. Can the messaging bridge use distributed destinations as source and target destinations?
A. Yes, the messaging bridge can send to and receive from distributed destinations. Bea
recommends the following configurations:
If the source is distributed destination, the bridge is pinned to one of the members when it
connects to the destination. It stays connected only to that member until it reconnects. This
means that the bridge will not receive messages from the other members of the distributed
destination. Therefore, the best practice is to configure one bridge for each member of a
distributed destinations using the member's JNDIName.
If the target is a distributed destination, the best practice is to send to the distributed
destination using the distributed destination’s JNDIName and disable server affinity. This
allows the distributed destination to load balance incoming messages.
Q. Why does the messaging bridge sometimes hang while processing messages?
A. By default, the AllowCloseInOnMessage attribute in the JMSConnectionFactory class is
set to false. To ensure that the server does not hang, set this value to true. For more
information, see:
162
Q. How can I incorporate MQSeries as an XA resource for distributed transactions in WebLogic
Server?
A. You can download a zip file with instructions, support classes, utilities, and an example from
the code samples for weblogic server page on BEA’s dev2dev site. You can also directly
download the package from
ftp://edownload:BUY_ME@ftpna2.bea.com/pub/downloads/wlsmqseries.zip.
Q. Can I use a non-XA driver in distributed transactions?
A. When the non-XA connection pool is the only resource participating in a transaction
distributed across multiple servers, you just need to configure a TxDataSource for the non-XA
driver.
However, when more than one resource participates in the distributed transaction, you must also
set the TxDataSource property EnableTwoPhaseCommit=true. For more information, see
Configuring JDBC DataSources in the Administration Console Online Help. In both cases,
always obtain a connection via the DataSource interface, not through the deprecated
DriverManager interface. If you obtain a connection via DriverManager, the interface cannot pick
up the EnableTwoPhaseCommit setting of the TxDataSource; this may result in unexpected
behavior in distributed transactions. Also, when you use the DataSource interface, you do not
need to distinguish either the URL or the specific WebLogic multitier driver (JTS, RMI, or pool.)
The URL and specific driver are obtained through the config.xml file and JNDI lookup.
Q. Can I use more than one non-XA connection pool in distributed transactions?
A. No. Even if you set EnableTwoPhaseCommit=true for both TxDataSources of the
connection pools, attempting to use two non-XA connection pools in the same distributed
transaction will result in:
"java.sql.SQLException: Connection has already been created in this tx context for pool named
name>"
when you attempt to get the connection from the second non-XA connection pool.
Q. How do XA and non-XA drivers differ in distributed transactions?
A. The differences between XA and non-XA JDBC drivers are:
Atomicity Guarantee. An XA driver implements the XAResource interface and can
participate fully in the 2PC protocol driven by the WLS Transaction Manager. This
guarantees atomicity of updates across multiple participating resources.
163
However, a non-XA driver does not implement the XAResource interface and cannot fully
participate in the 2PC protocol. When using a non-XA driver in a distributed transaction,
WLS implements the XAResource wrapper on behalf of the non-XA driver. If the data
source property enableTwoPhaseCommit is set to true, then the WLS XAResource
wrapper returns XA_OK when the Transaction Manager invokes the prepare() method.
When the Transaction Manager invokes commit() or rollback() during the second
phase, the WLS XAResource wrapper delegates the commit() or rollback() call to the
non-XA JDBC connection. Any failure during commit() or rollback() results in
heuristic exceptions. Application data may be left in an inconsistent state as a result of
heuristic failure.
Redirecting Connections. A non-XA driver can be configured to perform updates in the
same distributed transaction from more than one process, as explained in Can I use a
non-XA driver in distributed transactions?. WLS internally redirects the JDBC calls made
from different processes to the same physical JDBC connection in one process. However,
when you use a XA driver, no such redirection will be done. Each process will use its own
local XA database connection, and the database ensures that all the distributed updates
made in the same distributed transaction from different processes will be committed
atomically.
Connection Management. Whether you are using the non-XA driver or XA driver in
distributed transactions, WLS implements JDBC wrappers that intercept all the JDBC calls
and obtains a physical JDBC connection from the connection pool on demand.
– When you use a non-XA driver in distributed transactions, in order to ensure that
updates made from different processes are committed atomically, WLS associates the
same physical JDBC connection with the distributed transaction until it is committed or
rolled back. As a result, the number of active distributed transactions using the non-XA
connection pool is limited by the maximum capacity of the JDBC connection pool.
– When you use an XA driver, the connection management is more scalable. WLS does
not hold on to the same physical XA connection until the transaction is committed or
rolled back. In fact, in most cases, the XA connection as only held for the duration of a
method invocation. WLS JDBC wrappers intercept all JDBC calls and enlist the
XAResource associated with the XA connection on demand. When the method
invocation returns to the caller, or when it makes another call to another server, WLS
delists the XAResource associated with the XA connection.
– WLS also returns the XA connection to the connection pool on delistment if there are
no open result sets. Also, during commit processing, any XAResource object can be
used to commit any number of distributed transactions in parallel. As a result, neither
the number of active distributed transactions using the XA connection pool nor the
number of concurrent commit/rollbacks is limited by the maximum capacity of the
164
connection pool. Only the number of concurrent database access connections is limited
by the maximum capacity of the connection pool.
Q. What XA drivers can I use in addition to the WebLogic jDriver for Oracle/XA?
A. Theoretically, you can use any third party XA driver that is compliant with the JDBC 2.0
standard extension specification with WLS. However, an individual vendor's XA driver may
have bugs that prevent it from working properly.
Refer to JDBC Configuration guidelines for details about how to configure them at Using
Third-Partjy Drivers with WebLogic Server in Programming WebLogic JDBC.
Q. Can I use the Oracle thin driver as an XA driver in distributed transactions?
A. Oracle 8.1.7 thin driver has threading problems, so BEA developed the following
workaround: We use a dedicated XA connection for the duration of prepare, commit, and rollback
operation. This is different from the default XA connection management model in that any
XAResource object is used to commit any number of transactions in parallel. This limits the
number of concurrent commits to the max capacity of the XA connection pool. Note that this
workaround is an Oracle specific workaround and will not affect the usage of other XA drivers.
Q. Why do I get SQLException “Result set already closed” message?
Problem: I am using WebLogic jDriver for Oracle/XA (transaction mode) from the client side.
Updating in a distributed transaction works fine. However, when I try to perform a query, I get
SQLException Result set already closed. How do I work around this?
A. WebLogic jDriver for Oracle has a limitation that closes all open result sets when the method
returns to the caller.
Using the driver from the server side, for example, in a bean, does not have this limitation. Using
the driver from the server side is also recommended from application architecture and
performance perspective. Using the driver from the client side incurs round-trip cost for every
JDBC call being made.
This limitation exists because WebLogic jDriver for Oracle XA is implemented using Oracle's
OCI API and C XA switch, and there is an Oracle problem when using OCI with XA in
multi-threaded mode. Closing an OCI cursor in a thread that is different than the thread in which
it is opened may result in server crash or unexpected behavior. As a result, the WebLogic driver
implicitly closes all open result sets upon returning a call to the caller.
Q. Do I need a 2PC licence when I use JMS with one JDBC non-XA driver?
165
A. Yes, you do. JMS is also a XAResource that participates in the distributed transaction.
Therefore, there are two resources participating in the distributed transaction, and a 2PC license
is needed.
Q. Why am I getting an exception when I use JMS with a non-XA driver?
Problem: I am using JMS with one JDBC non-XA driver. Transaction fails to commit with the
following exception javax.transaction.xa.XAException: JDBC driver does not
support XA, hence cannot be a participant in two-phase commit.
A. As mentioned in the previous question “Do I need a 2PC licence when I use JMS with one
JDBC non-XA driver?”, JMS is also a XAResource that participates in the distributed
transaction. When more than one resource is participating in the distributed transaction, you need
to set the data source property EnableTwoPhaseCommit=true as explained in “Can I use a
non-XA driver in distributed transactions?”
Q. Can I obtain a JDBC connection before I start a distributed transaction?
A. This depends on whether you are using a non-XA or XA driver.
When you use a non-XA driver in a distributed transaction, always obtain a JDBC
connection after the distributed transaction is begun.
If you are using an XA driver, you can obtain the connection before or after the distributed
transaction begins.
Q. Can I close a JDBC connection after the distributed transaction is committed or rolled back?
A. For both non-XA and XA driver, you can close the connection after the distributed transaction
is completed.
Q. I get the following XAER_RMFAIL XAException when accessing an XAResource: "Internal
error: XAResource '
A. JTA has its own resource health monitoring that works as follows:
A resource is considered active either if there are no pending requests or if we get a result from
any of the XAResource pending requests that is not an XAER_RMFAIL. If an XAResource is not
active within the two minutes, it is declared dead. Any further requests to the XAResource are
shunned, and an XAER_RMFAIL XAException as above is thrown. The intent is to prevent further
loss of threads if the RM is dead.
A resource is declared active again, if you re-register the XAResource with the WebLogic Server
Transaction Manager by calling
166
weblogic.transaction.TransactionManager.unregisterResource followed by
registerStaticResource or registerDynamicResource, or after a timeout period of 30
minutes. If you are using WLS JDBC connection pools, you only need to enable the JDBC
connection pool refresh feature (by specifying the "RefreshMinutes" property of the connection
pool), and, upon a successful connection pool refresh, the corresponding XAResource will be
re-registered automatically. If you are registering your own XAResource, either via
weblogic.transaction.TransactionManager.registerStaticResource or
registerDynamicResource APIs, you will need to re-register the XAResource by calling
weblogic.transaction.TransactionManager.unregisterResource followed by
registerStaticResource or registerDynamicResource.
In general, a good way to debug potential RM problems is to turn on JTA XA debugging, by
specifying -Dweblogic.Debug=weblogic.JTAXA as JVM parameter on WLS startup.
0 comments:
Post a Comment