Thursday, August 14, 2008

WebLogic Q & A - 3

© Moreniche

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 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:

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 Messaging Bridge Configuration General tab.

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 Monitor Messaging Bridge

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 Messaging Bridge in the Console

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

. Illegal attempt to create connection from another pool:

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 '' is unavailable". What does that mean? How should I handle it?

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: