Tag: Messaging Bridge

How to Configure Weblogic Messaging Bridge with JBoss

Ravish Mody

One of our subscriber ravikumar was trying to configure Weblogic (10.3.0) messaging bridge with JBoss (3.24) and was getting below error

<Warning> <Connector> <BEA-190032> << eis/jms/WLSConnectionFactoryJNDINoTX > ResourceAllocationException thrown by resource adapter on call to ManagedConnectionFactory.createManagedConnection(): “javax.resource.ResourceException: Failed to start the connection “>

So I had taken some time out and configured the same and was able to send messages from weblogic server to JBoss queue successfully. Hence wanted to share the it with all other who are trying to configure weblogic messaging bridge with JBoss.

I would be using the below configuration and version of Weblogic server and JBoss server.

Weblogic version: 10.3.0
JBoss version: AS 5.1
Bridge is on Weblogic
Source Bridge Destination is Weblogic server queue
Target Bridge Destination is JBoss queue

Now the main thing which you have to keep in mind before configuring weblogic messaging bridge with any 3rd party/any other JMS provider is that you have to get the right set of JAR files or else you would get lot of issue as the shown above and your configuration would not work properly, thus for this configuration you have to get the following JAR files from JBoss side and put it in the classpath of weblogic or put them in the Domain/lib folder.

Minimum JBoss JAR required:

From: /jboss-as/client
To: /WLS_Domain_Name/lib

  1. concurrent.jar
  2. javassist.jar
  3. jboss-aop-client.jar
  4. jboss-common-core.jar
  5. jboss-logging-spi.jar
  6. jboss-messaging-client.jar
  7. jboss-remoting.jar
  8. jnp-client.jar
  9. log4j.jar
  10. trove.jar

NOTE: These jars are from the JBoss version EAP 5.1.0 if you are using higher or lower version then you might have to put more or less jars. To get which jars you might need then the best option is to use the weblogic messaging bridge debug flags (DebugMessagingBridgeRuntime,  DebugMessagingBridgeRuntimeVerbose,  DebugMessagingBridgeStartup) which would show you the something like below error and then you have to use the SCANJAR at JBoss level to get the corresponding jars.

java.lang.ClassNotFoundException: org.jboss.logging.Logger

Now comes the configuration part from Weblogic side, to get a step by step configuration have a look at this post –> Weblogic Messaging Bridge on Weblogic Server. Here I would be only concentrating on the Source Bridge Destination and Target Bridge Destination which are shown below.

Source Bridge Destination

Name: Source_BridgeDestination
Adapter JNDI Name: eis.jms.WLSConnectionFactoryJNDINoTX
Classpath:
Connection URL: t3://<HOSTNAME or IP-ADDRESS>:<PORT>
Initial Context Factory: weblogic.jndi.WLInitialContextFactory
Connection Factory JNDI Name: <JNDI_OF_CONNECTION_FACTORY>
Destination JNDI Name: <JNDI_OF_QUEUE>
Destination Type: Queue
User Name: <USERNAME>
User Password: <PASSWORD>
Confirm User Password: <PASSWORD>

SourceBridgeDestination - Weblogic Server

SourceBridgeDestination - Weblogic Server

<jms-bridge-destination>
   <name>Source_BridgeDestination</name>
   <adapter-jndi-name>eis.jms.WLSConnectionFactoryJNDINoTX</adapter-jndi-name>
   <user-name>weblogic</user-name>
   <user-password-encrypted>{3DES}oFQLW2mB0rGKThL75ieYBQ==</user-password-encrypted>
   <classpath></classpath>
   <connection-factory-jndi-name>CF</connection-factory-jndi-name>
   <initial-context-factory>weblogic.jndi.WLInitialContextFactory</initial-context-factory>
   <connection-url>t3://localhost:7001</connection-url>
   <destination-jndi-name>Q</destination-jndi-name>
   <destination-type>Queue</destination-type>
</jms-bridge-destination>

Traget Bridge Destination

Name: Traget_Bridge_Destination
Adapter JNDI Name: eis.jms.WLSConnectionFactoryJNDINoTX
Classpath:
Connection URL: jnp://<HOSTNAME or IP-ADDRESS>:<PORT>
Initial Context Factory: org.jnp.interfaces.NamingContextFactory
Connection Factory JNDI Name: <JNDI_OF_CONNECTION_FACTORY>
Destination JNDI Name: <JNDI_OF_QUEUE>
Destination Type: Queue
User Name:
User Password:
Confirm User Password:

TragetBridgeDestination - JBoss Setting

TragetBridgeDestination - JBoss Setting

<jms-bridge-destination>
   <name>Traget_Bridge_Destination</name>
   <adapter-jndi-name>eis.jms.WLSConnectionFactoryJNDINoTX</adapter-jndi-name>
   <user-password-encrypted xsi:nil="true"></user-password-encrypted>
   <classpath></classpath>
   <connection-factory-jndi-name>XAConnectionFactory</connection-factory-jndi-name>
   <initial-context-factory>org.jnp.interfaces.NamingContextFactory</initial-context-factory>
   <connection-url>jnp://localhost:1099</connection-url>
   <destination-jndi-name>queue/TestQ</destination-jndi-name>
   <destination-type>Queue</destination-type>
</jms-bridge-destination>

Bridge

Name: Bridge
Source Bridge Destination: Source_BridgeDestination
Target Bridge Destination: Traget_Bridge_Destination
Selector:
Quality Of Service: Atmost-once
QOS Degradation Allowed: Un-checked
Maximum Idle Time: 60
Asynchronous Mode Enabled: Checked
Durability Enabled: Checked
Started: Checked
Preserve Msg Property: Un-checked

<messaging-bridge>
   <name>Bridge</name>
   <target>AdminServer</target>
   <source-destination>Source_BridgeDestination</source-destination>
   <target-destination>Traget_Bridge_Destination</target-destination>
   <selector></selector>
   <quality-of-service>Atmost-once</quality-of-service>
   <qos-degradation-allowed>false</qos-degradation-allowed>
   <durability-enabled>true</durability-enabled>
   <idle-time-maximum>60</idle-time-maximum>
   <async-enabled>true</async-enabled>
   <started>true</started>
   <preserve-msg-property>false</preserve-msg-property>
</messaging-bridge>

Testing:

Now lets test our configuration if its working fine by using the following snip-code.

In QueueSend.java copy the below command:

import java.io.*;
import java.util.Hashtable;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class QueueSend
{
public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";

// ******* Give the CONNECTION FACTORY JNDI name which is QCF from WEBLOGIC side  ********
public final static String JMS_FACTORY="QCF";

// ******* Give the QUEUE JNDI name which is Q from WEBLOGIC side  ********
public final static String QUEUE="Q";

private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueSender qsender;
private Queue queue;
private TextMessage msg;

public void init(Context ctx, String queueName)
throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
qcon.start();
}

public void send(String message) throws JMSException {
msg.setText(message);
qsender.send(msg);
}

public void close() throws JMSException {
qsender.close();
qsession.close();
qcon.close();
}

public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("Usage: java QueueSend WebLogicURL");
return;
}
InitialContext ic = getInitialContext(args[0]);
QueueSend qs = new QueueSend();
qs.init(ic, QUEUE);
readAndSend(qs);
qs.close();
}

private static void readAndSend(QueueSend qs) throws IOException, JMSException
{
String line="Test Message Body with counter = ";
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
boolean readFlag=true;
System.out.println("ntStart Sending Messages (Enter QUIT to Stop):n");
while(readFlag)
{
System.out.print("&lt;Msg_Sender&gt; ");
String msg=br.readLine();
if(msg.equals("QUIT") || msg.equals("quit"))
{
qs.send(msg);
System.exit(0);
}
qs.send(msg);
System.out.println();
}
br.close();
}

private static InitialContext getInitialContext(String url) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
}

In QueueReceive.java copy the below command:

import java.util.Hashtable;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class QueueReceive implements MessageListener
{
// ******* Give the INITIAL CONTEXT FACTORY name which is of JBOSS side ********
public final static String JNDI_FACTORY="org.jnp.interfaces.NamingContextFactory";

// ******* Give the CONNECTION FACTORY JNDI name which is QCF from JBOSS side ********
public final static String JMS_FACTORY="/XAConnectionFactory";

// ******* Give the QUEUE JNDI name which is TestQ from JBOSS side  ********
public final static String QUEUE="/queue/TestQ";

private QueueConnectionFactory qconFactory;
private QueueConnection qcon;
private QueueSession qsession;
private QueueReceiver qreceiver;
private Queue queue;
private boolean quit = false;

public void onMessage(Message msg)
{
try {
String msgText;
if (msg instanceof TextMessage)
{
msgText = ((TextMessage)msg).getText();
}
else
{
msgText = msg.toString();
}
System.out.println("nt<Msg_Receiver> "+ msgText );
if (msgText.equalsIgnoreCase("quit"))
{
synchronized(this)
{
quit = true;
this.notifyAll(); // Notify main thread to quit
}
}
}
catch (JMSException jmse)
{
jmse.printStackTrace();
}
}
public void init(Context ctx, String queueName) throws NamingException, JMSException
{
qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup(queueName);
qreceiver = qsession.createReceiver(queue);
qreceiver.setMessageListener(this);
qcon.start();
}

public void close()throws JMSException
{
qreceiver.close();
qsession.close();
qcon.close();
}

public static void main(String[] args) throws Exception
{
if (args.length != 1)
{
System.out.println("Usage: java QueueReceive WebLogicURL");
return;
}
InitialContext ic = getInitialContext(args[0]);
QueueReceive qr = new QueueReceive();
qr.init(ic, QUEUE);
System.out.println("JMS Ready To Receive Messages (To quit, send a "quit" message from QueueSender.class).");
// Wait until a "quit" message has been received.
synchronized(qr)
{
while (! qr.quit)
{
try
{
qr.wait();
}
catch (InterruptedException ie)
{}
}
}
qr.close();
}

private static InitialContext getInitialContext(String url) throws NamingException
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
}

– Now for QueueSend.java you have to use the t3://<HOST>:<PORT>  (i.e. as Source Bridge Destination queue is at Weblogic Server )

– And for QueueReceive.java you have to use the jnp://<HOST>:<PORT> (i.e. as Target Bridge Destination queue is at JBoss Server )

Output

Output


JMS Demo using WebLogic Messaging Bridge

Ravish Mody

To configure a Messaging Bridge you can follow the steps provided in the post Steps to Configure Messaging Bridge on Weblogic Server

In this post I would be using a stand-alone java code for producing messages as a Producer/Clint and  for consuming the messages as a Consumer/Listener. By which we can make sure that if something goes wrong then we can narrow down the issue if its an issue with WLS or the code, asmany times their an issue with the Producer or a Consumers.

.

.

Steps of test the Messaging Bridge

  1. Create a Directory somewhere in your file system like: “D:OracleJMSQueue” to write the QueueSend.java and QueueReceive.java programs.
  2. In QueueSend.java copy the below command
    
    import java.io.*;
    import java.util.Hashtable;
    import javax.jms.JMSException;
    import javax.jms.Queue;
    import javax.jms.QueueConnection;
    import javax.jms.QueueConnectionFactory;
    import javax.jms.QueueSender;
    import javax.jms.QueueSession;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    public class QueueSend
    {
    public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
    
    // ******* Give the CONNECTION FACTORY JNDI name which is QCF ********
    public final static String JMS_FACTORY="QCF";
    
    // ******* Give the UNIFORM DISTRIBUTED QUEUE JNDI name which is TestQ   ********
    public final static String QUEUE="TestQ";
    
    private QueueConnectionFactory qconFactory;
    private QueueConnection qcon;
    private QueueSession qsession;
    private QueueSender qsender;
    private Queue queue;
    private TextMessage msg;
    
    public void init(Context ctx, String queueName)
    throws NamingException, JMSException
    {
    qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
    qcon = qconFactory.createQueueConnection();
    qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    queue = (Queue) ctx.lookup(queueName);
    qsender = qsession.createSender(queue);
    msg = qsession.createTextMessage();
    qcon.start();
    }
    
    public void send(String message) throws JMSException {
    msg.setText(message);
    qsender.send(msg);
    }
    
    public void close() throws JMSException {
    qsender.close();
    qsession.close();
    qcon.close();
    }
    
    public static void main(String[] args) throws Exception {
    if (args.length != 1) {
    System.out.println("Usage: java QueueSend WebLogicURL");
    return;
    }
    InitialContext ic = getInitialContext(args[0]);
    QueueSend qs = new QueueSend();
    qs.init(ic, QUEUE);
    readAndSend(qs);
    qs.close();
    }
    
    private static void readAndSend(QueueSend qs) throws IOException, JMSException
    {
    String line="Test Message Body with counter = ";
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    boolean readFlag=true;
    System.out.println("ntStart Sending Messages (Enter QUIT to Stop):n");
    while(readFlag)
    {
    System.out.print("&lt;Msg_Sender&gt; ");
    String msg=br.readLine();
    if(msg.equals("QUIT") || msg.equals("quit"))
    {
    qs.send(msg);
    System.exit(0);
    }
    qs.send(msg);
    System.out.println();
    }
    br.close();
    }
    
    private static InitialContext getInitialContext(String url) throws NamingException
    {
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
    env.put(Context.PROVIDER_URL, url);
    return new InitialContext(env);
    }
    }
    
  3. In QueueReceive.java copy the below command
    import java.util.Hashtable;
    import javax.jms.*;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    public class QueueReceive implements MessageListener
    {
    public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory";
    
    // ******* Give the CONNECTION FACTORY JNDI name which is QCF ********
    public final static String JMS_FACTORY="QCF";
    
    // ******* Give the UNIFORM DISTRIBUTED QUEUE JNDI name which is TestQ   ********
    public final static String QUEUE="TestQ";
    private QueueConnectionFactory qconFactory;
    private QueueConnection qcon;
    private QueueSession qsession;
    private QueueReceiver qreceiver;
    private Queue queue;
    private boolean quit = false;
    
    public void onMessage(Message msg)
    {
    try {
    String msgText;
    if (msg instanceof TextMessage)
    {
    msgText = ((TextMessage)msg).getText();
    }
    else
    {
    msgText = msg.toString();
    }
    System.out.println("nt&lt;Msg_Receiver&gt; "+ msgText );
    if (msgText.equalsIgnoreCase("quit"))
    {
    synchronized(this)
    {
    quit = true;
    this.notifyAll(); // Notify main thread to quit
    }
    }
    }
    catch (JMSException jmse)
    {
    jmse.printStackTrace();
    }
    }
    public void init(Context ctx, String queueName) throws NamingException, JMSException
    {
    qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
    qcon = qconFactory.createQueueConnection();
    qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    queue = (Queue) ctx.lookup(queueName);
    qreceiver = qsession.createReceiver(queue);
    qreceiver.setMessageListener(this);
    qcon.start();
    }
    
    public void close()throws JMSException
    {
    qreceiver.close();
    qsession.close();
    qcon.close();
    }
    
    public static void main(String[] args) throws Exception
    {
    if (args.length != 1)
    {
    System.out.println("Usage: java QueueReceive WebLogicURL");
    return;
    }
    InitialContext ic = getInitialContext(args[0]);
    QueueReceive qr = new QueueReceive();
    qr.init(ic, QUEUE);
    System.out.println("JMS Ready To Receive Messages (To quit, send a "quit" message from QueueSender.class).");
    // Wait until a "quit" message has been received.
    synchronized(qr)
    {
    while (! qr.quit)
    {
    try
    {
    qr.wait();
    }
    catch (InterruptedException ie)
    {}
    }
    }
    qr.close();
    }
    
    private static InitialContext getInitialContext(String url) throws NamingException
    {
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
    env.put(Context.PROVIDER_URL, url);
    return new InitialContext(env);
    }
    }
    
  4. Now open 2 – command promt Windows and run “setWLSEn.cmd” in all the three Command Windows to set the Environment (PATH & CLASSPATH).
  5. Then compile the QueueSend.java and QueueReceive.java programs.
  6. Now run the code with the following command
  7. Prompt-1

    java QueueSend t3://localhost:8001
     

    Prompt-2

    java QueueReceive t3://localhost:7001
     

    Note:

    With the “java QueueSend” and “java QueueReceive” command you have to give the<Protocol>://<IP-address>:<Port number>of the managed servers in different prompts.

  8. Once this is been done try to send few messages in the Prompt one  which is sending to the port 8001 which the Source Detonation in Domain-1 , however you will notice that the message would be received on Prompt-2 which is listening on port 7001 which the Target Detonation in Domain-2 as shown in the below snap-shot.
  9. JMS Bridge Demo

    JMS Bridge Demo

    .
    Thus this way we can see that using weblogic messaging bridge we can transfer messages from one domain to the second domain easily.

    .

    Thanks,

    Ravish Mody


Steps to Configure Messaging Bridge on Weblogic Server

Ravish Mody

Today one of our subscriber Chandu had asked me by commenting to provide the necessary configurations that can be done so that he can send the messages from one domain to other domain using JMS, hence I have chosen messaging bridge to do this job that’s why I am writing this post so that others can also take the benefits out of it. For demo you can check this post JMS Demo using WebLogic Messaging Bridge

So lets talk about messaging bridge like what is it, how things work in messaging bridge and what are the steps to configure it to send a message from one domain to another.

.

What is Messaging Bridge?

In simple words messaging bride is a type of forwarding mechanism for messages, which also provides interoperability between weblogic JMS implementations and between any other JMS messaging products like MQ or even can be used to between two different domains of weblogic server which can be in the same version or different versions.

Note: It is recommended that the messaging bridge should be configured on the higher version between any weblogic server version.

How does Messaging Bridge works?

As I told you that messaging bridge is a type of forwarding mechanism in which it has a Source Destination and a Target Destination which used with Java EE Connector Architecture (JCA) Resource adapters provided with weblogic server to send the messages from one place to other.

Source Destination – Means from where the messages are been read/picked up.

Target Destination – Means where the picked up messages has to be sent.

Resource adapter – It is uses JCA resource adapters to communicate with the configured source and target JMS destinations which gets deployed automatically (not in WLS 8.1) when we configure messaging bridge.

Steps to configure Messaging Bridge:

1.  You have to follow steps from Step-1 to Step-5 from the post Basic JMS Demo using WebLogic Queue. For Domain-1 running on port 8001 and again same steps on Domain-2 running on port 7001.

2.   After you have configured JMSServer, FileStore, System Module, Connection Factory and Queue on two different domains now we would start configuring the Bridge on Domain-1 having port 8001.

3.  Configure Source Bridge Destination

JMS Bridge-1

Creating Source Destination

JMS Bridge-2

Configuring Source Destination - URL = t3://localhost:8001

4.  Configure Target Bridge Destination

JMS Bridge-3

Creating Target Destination

JMS Bridge-4

Configuring Target Destination - URL = t3://localhost:7001

5.  Configure Messaging Bridge using source and target destination

JMS Bridge-5

Creating Messaging Bridge

JMS Bridge-6

Configuring Messaging Bridge

JMS Bridge-7

Selecting Source Destination

JMS Bridge-8

Selecting Messaging Provider for Source Destination

JMS Bridge-9

Selecting Target Destination

JMS Bridge-10

Selecting Messaging Provider for Target Destination

JMS Bridge-11

Targeting Messaging Bridge

JMS Bridge-12

Finishing Messaging Bridge Configuration

That’s it, your configuration for messaging bridge has been finished and its ready to send messages from the queue in Domain-1 having the port 8001 to the queue in Domain-2 having the port 7001. Hope this would help others too.

Regards,

Ravish Mody


Copyright © 2010-2012 Middleware Magic. All rights reserved. |