The Confusion Chronicle

February 16, 2010

Configuring WLS Messaging Bridge with Foreign JMS

Filed under: Computing,JMS,WebLogic Server — Tim @ 12:35 pm

It’s a pretty common scenario. There is a need to get messages to and from different WebLogic servers and domains or from another JMS provider (insert you favourite in here). In WLS 9.2 and later, there are three possible scenarios for doing this sort of work; SAF which allows for WLS 9.2 and later JMS interopt only; Foreign JMS and the Messaging Bridge, which allow for pretty much any sort of JMS provider.

This article deals with the last of these three.

The messaging bridge was introduced into WebLogic in WLS 7, although it does appear in the later service packs of WLS 6. The messaging bridge isn’t the recommended method of performing system to system transfer of JMS messages in WLS 9.2 and later – for WLS to WLS transfers, SAF is the preferred method (although there are a number of critical bugs reported) and for Foreign (non WLS) JMS providers, the foreign JMS service is provided.

The WebLogic Server’s Messaging bridge relies on a couple of JCA adapters that are shipped with WLS and you can write your own, although these aren’t supported and to be honest it isn’t recommended. The two that are shipped are the transactional adapter (jms-xa-adp.rar) and the nontransactional adapter (jms-notran-adp.rar)- both of which are used to connect to WLS 7.0 and later, and the various foreign JMS containers. there is a third adapter that is seen on various releases of WLS, the 5.1 adapter (jms-notran-adp51.rar), but frankly this isn’t supported anymore and if you using WLS 5.1, WLS has made a lot of advances!

How to set it up

Below is a simple guide that details how to setup WLS JMS from WebLogic Server 10.3 using the messaging bridge to talk to a Foreign JMS, in this case Tibco’s EMS. In this example I’ve used the XA adpater, simply because it’s used the most. . A lot of the problems that I have seen are due to a misconfiguration.

1) Firstly configure a JMS Server and a JMS module. The module contains that JMS Connection Factory and the JMS queue.  Mine are originally named and I’ve jms module that contains the following entries

<connection-factory name=”BridgeCF”>
<default-targeting-enabled>true</default-targeting-enabled>
<jndi-name>BridgeCF</jndi-name>
<transaction-params>
<xa-connection-factory-enabled>true</xa-connection-factory-enabled>
</transaction-params>
<security-params>
<attach-jmsx-user-id>false</attach-jmsx-user-id>
</security-params>
</connection-factory>
<queue name=”BridgeQueue”>
<sub-deployment-name>BridgeQueue</sub-deployment-name>
<jndi-name>BridgeQueue</jndi-name>
</queue>

The important things to note are that the connection factory (in red) is enabled for XA transactions as we are using the jms-xa-adp.rar for the messaging bridge adapter. In the console this option is here.

Additionally, on Tibco, you’ll need to create the target Queue and Connection factory. In simpliest terms, the commands for this are

create queue bridgequeue (for the jms queue)

create factory xacf xaqueue (for the jms xa-complient connection factory)

2) Once these are done, the source and target for the messaging bridge need to be created. You can create these on the fly, as you create the messaging bridge, but I’d suggest that they are created first. Look in the domain structure for the JMS Bridge destinations

Then you need to click on “NEW” to create a new destination. You are presented with the following screen

for each destination you ‘ll need to add the following

NAME – anything you like

Adpater JNDI name – for the purpose of this guide, just the eis.jms.WLSConnectionFactoryJNDIXA. This is the XA complient one.

Adpater Classpath – Leave Blank. It’s for custom built adapters

Connection URL – the URL representing the JMS provider

For WebLogic, this is generally given in the format t3://<host>:<port> – t3://localhost:7001 being the default
For Tibco, this is generally given in the format tibjmsnaming://<host>:<port> – tinjmsnaming://localhost:7222 being the default

Connection Factory JNDI Name – the respective connection factory for each provider

BridgeCF for the XA connection factory that I created on WebLogic
xacf for the XA  connection factory that I created on Tibco EMS

Unfortunately, if you need to add a user credentials to either of the bridges, you need to edit them after you have created the bridges, there is no way to add the credentials as the bridge is being created.

<jms-bridge-destination>
<name>Tibco</name>
<adapter-jndi-name>eis.jms.WLSConnectionFactoryJNDIXA</adapter-jndi-name>
<user-password-encrypted></user-password-encrypted>
<classpath></classpath>
<connection-factory-jndi-name>xacf</connection-factory-jndi-name>
<initial-context-factory>com.tibco.tibjms.naming.TibjmsInitialContextFactory</initial-context-factory>
<connection-url>tibjmsnaming://localhost:7222</connection-url>
<destination-jndi-name>bridgequeue</destination-jndi-name>
<destination-type>Queue</destination-type>
</jms-bridge-destination>

<jms-bridge-destination>
<name>WebLogic</name>
<adapter-jndi-name>eis.jms.WLSConnectionFactoryJNDIXA</adapter-jndi-name>
<user-name>weblogic</user-name>
<user-password-encrypted>{3DES}MlaFMKCE5WXHSStVu8kRWw==</user-password-encrypted>
<classpath></classpath>
<connection-factory-jndi-name>BridgeCF</connection-factory-jndi-name>
<initial-context-factory>weblogic.jndi.WLInitialContextFactory</initial-context-factory>
<connection-url>t3://tdaly01:7001</connection-url>
<destination-jndi-name>BridgeQueue</destination-jndi-name>
<destination-type>Queue</destination-type>
</jms-bridge-destination>

3) Update Weblogic’s CLASSPATH to include the Tibco client side rar file. I usually add this to the end of the setDomainenv.sh/setDomainEnv.cmd from the $DOMAIN_HOME/bin directory. assuming that you have a default tibco insallation on widow the file needed is C:\tibco\ems\5.1\lib\tibjms.jar

4) Create the bridge. If you navigate under the domain structure to messaging – > bridge, it’s here that you can create a new bridge.

Here the important bits to note are the Quality of Service field and the “Started” flag. The former should be set to the quality of service that you want to achieve – Exactly Once (the message is forwarded once and once only) being the highest and At Most Once (it might get there, it might not, who knows?!)  being the lowest. Personally, I’ve never seem the point of At Most Once. With the XA configuration, Exactly Once seems the obvious choice and is the only choice. The started flag dictates if you want the bridge to start up automatically when starting WebLogic or when the bridge is deployed.

The next two screen allow you to set the source destination.

If you want to create the destinations on the fly, this is the point that you do it at (select New Destination, the button circled in blue). If you’ve already created the destinations, it’s just a question of selecting them and the correct JMS provider. The next two screens are identical; this is where you configure the target destination.

Select the correct WebLogic server to target to and then finish.

I would like to point out that there are a couple of bugs in this area, to do with reconnecting to foreign JMS servers. I can’t distribute the bugs but there is a knowledge article on the bugs required – bug8066979 and bug8172940 that apply to WLS 10Mp1 and WLS 10.3. These issues are fixed in WLS 10.3.3 (not yet released).

Other JMS providers

These same instructions could be used for any JMS , just replace the URL, Initial Context Factory and the client side jars files for those of the relevant JMS provider. I’ve listed some here

JMS provider Sample URL Initial Context Factory Client jar file needed
Weblogic t3://<host>:<port> weblogic.jndi.WLInitialContextFactory n/a
Tibco tibjmsnaming://<host>:<port>tcp://<host>:<port> com.tibco.tibjms.naming.TibjmsInitialContextFactory tibjms.jar
WebSphere MQ file:/C:/JNDI-Directory [1] com.sun.jndi.fscontext.RefFSContextFactory com.ibm.mq.jar
com.ibm.mqjms.jar
Active MQ tcp://<host>:<port> org.apache.activemq.jndi.ActiveMQInitialContextFactory activemq-core-x.x.x.jar [2]
Sonic MQ tcp://<host>:<post> com.sonicsw.jndi.mfcontext.MFContextFactory Sonic_client.jar Sonic_XA.jar

[1] WebSphere MQ implements JNDI through file bindings. It’s this file that is the URL

[2] The Active MQ client side jar file is dependant on the precise version

Messaging bridge debugging options on WebLogic

The debugging options for the bridge are actually documented here, but there is the most verbose of these options missing -
-Dweblogic.debug.DebugMessagingBridgeRuntimeVerbose=true
This tells you the state of the bridge and can be useful, but as the states are numbers and not documented, intuition is needed.

The output from the other debug is  particularly useful as the standard error messages frequently give vague exceptions. In turning on the debugging, we can see messages such as

<09-Feb-2010 12:04:43 o’clock GMT> <Debug> <MessagingBridgeStartup> <BEA-000000> <creating bridge Bridge-0>
<09-Feb-2010 12:04:43 o’clock GMT> <Debug> <MessagingBridgeStartup> <BEA-000000> <Bridge Bridge-0′s source configurations are:
AdapterJNDIName=eis.jms.WLSConnectionFactoryJNDIXA
Classpath=
ConnectionURL = t3://tdaly01:7001
DestinationType = Queue
DestinationJNDIName = BridgeQueue
InitialContextFactory = weblogic.jndi.WLInitialContextFactory
ConnectionFactoryJNDIName = BridgeCF
>
<09-Feb-2010 12:04:43 o’clock GMT> <Debug> <MessagingBridgeStartup> <BEA-000000> <Bridge Bridge-0′s target configurations are:
AdapterJNDIName=eis.jms.WLSConnectionFactoryJNDIXA
Classpath=
ConnectionURL = tibjmsnaming://localhost:7222
DestinationType = Queue
DestinationJNDIName = bridgequeue
InitialContextFactory = com.tibco.tibjms.naming.TibjmsInitialContextFactory
ConnectionFactoryJNDIName = xacf
>
<09-Feb-2010 12:04:43 o’clock GMT> <Debug> <MessagingBridgeStartup> <BEA-000000> <Bridge Bridge-0 is successfully initialized>

which confirms how the messaging bridge is configured at startup. The entry below is more useful as it shows when the messages are sucessfully sent.

<09-Feb-2010 12:05:53 o’clock GMT> <Debug> <MessagingBridgeRuntime> <BEA-000000> <Bridge: Bridge-0 (onMessage()) successfully sent message:

JMS Message Class: TextMessage
Old JMS MessageID: ID:<131030.1265368248390.0>
New JMS MessageID: ID:EMS-SERVER.AC84B714EB24:2675
I am a really long message that has been successfully for…
>

If you’ve got problems you won’t be looking at these entries, but at the exceptions and the detailled debug information. I think that mostly these are very easy to understand.

There are other debugging scopes that can be extremely useful for looking into messaging bridge issues
1) DebugMessagingKernel and DebugJMSBackEnd. These are always useful for most JMS related issues. The DebugMessagingKernel is verbose, but tracks each message by the ID; the backendJMS is less vebose and allows you to identify a problem within the specific area of the JSM subsystem.
2) JTA2PC and JTAXA are both very useful for identifying an issue with the transaction part of the messaging bridge as the provide verbose information on the transaction states of the messages that the bridge is forwarding.
3) The weblogic.connector debug scope also has many options. This scope covers the debugging options for the JCA adapter, but it is detailled. to be avoided unless you know what you are doing.

5 Comments »

  1. These comments come via TRobert Wyatt, of IBM. He mailled them to me.

    I saw two things that seemed significant. The first was “WebSphere MQ implements JNDI through file bindings”. Actually, WMQ doesn’t implement JNDI at all, it just uses any JNDI compliant provider. It comes with classes for LDAP and FSContext but I’ve seen people use all kinds of JNDI providers. As long as you have a provider class to point WMQ or JMSAdmin at, it should work.

    The other thing was that you had specified an XA connection factory. Was not sure if you knew that WMQ will not do two-phase commit with the free client. It doesn’t complain about an XA connection factory as long as there’s only one resource manager. It just optimizes down to 1PC anyway. But if you need to update WMQ and a DB in the same transaction, the Extended Transactional Client is required. Very often we see people discussing etclient.jar and even emailing or posting it online. This is the component in WMQ that gives you 2PC, but it is actually part of the WMQ Server distribution and incurs the license cost of a full WMQ server.

    and also

    The other thing I just noticed is the “Client Jar File Needed” column in the table. The classes seem to be repackaged with each release so it’s dependent on which version of WMQ is used. For v6.x you want this CLASSPATH (scroll down to the second table for JMS) and for v7.x you want this one. The IBM-supported configuration is to install the full client rather than to grab the jar files. If you grab the jar files, be aware that the ones listed refer to others which must also be in the CLASSPATH.

    My current customer switched from WMQ v6 to WMQ v7 and relocated the WMQ jars to their PeopleSoft app’s CLASSPATH using the same CLASSPATH as for v6. Although it connected and could get and put messages, it was broken and seemed to fall back to JMS 1.0 behavior – i.e. no Destination or CF objects, just QCF, TCF, Queue and Topic.

    Comment by Tim — February 26, 2010 @ 12:47 am

  2. I noticed that Oracle AQ is missing from your table of “Other JMS providers”… why is that? Also, If it *IS* possible to setup Oracle AQ as a Foreign JMS Provider, how would the set up and configuration differ? Many Thanks!

    Comment by ConfusedCyberGuy7 — September 1, 2010 @ 12:40 am

  3. You cannot use a Messaging Bridge to interoperate with Oracle AQ directly. You can however use Foreign JMS to interoperate with Oracle AQ and the documentation is fairly explicit on this.

    http://download.oracle.com/docs/cd/E15523_01/web.1111/e13738/aq_jms.htm#CJACBCEJ

    What you could try is then using the messaging bridge to use the foreign JMS entries as the source or destination, but I’ve never tried doing this, so I don’t know for sure if it will work, but I imagine it will.

    Comment by Tim — September 8, 2010 @ 9:31 am

  4. Hi Tim,

    Is there anyway we can retain the JMS message id received from TIBCO EMS in target weblogic queue. The bridge is created at Weblogic end. “Preserve Message Properties” option is not working.

    Comment by Kailash — October 8, 2011 @ 7:10 pm

  5. If the message ID is stored within the message header using the standard JMS Message ID parameter, then the message ID should be preserved without issue.

    If you are testing with “Preserve Message Properties” and you are not seeing this behaviour, then contact oracle support. I’m not aware of any bugs in this area.

    Comment by Tim — October 11, 2011 @ 9:13 am

RSS feed for comments on this post. TrackBack URL

Leave a comment


+ seven = 16

Powered by WordPress