Tag: HornetQ

How to configure EJB3 MDBs on JBoss AS 7 for remote IBM Websphere MQ 7 ?

Almost a month back we had written an article Steps to Create A Remote Queue in WebSphere MQ 7 in which we had given the steps to configure a remote queue in WebSphere MQ and in the article How to configure EJB3 MDBs on JBoss AS 5.1 for remote IBM Websphere MQ 7? which showed the steps to connect with WebSphere MQ using AS 5.1.

However in this article we would be doing the same but using JBoss AS 7.1.1 final which is the latest version of JBoss AS 7.  We would be sharing the configuration from JBoss AS 7.1.1 final side which would help everyone to consume messages from Websphere MQ 7 which is residing on a remote box. We will also see how can one send messages (i.e. using a JAVA standalone code) to a remote queue on Box-1 having Websphere MQ 7 and those messages can be received by the consumer (i.e. using EJB3 MDB deployed on JBoss) from Box-2 which is a very basic scenario in most of the people.

The main concept for this is that we would be sending messages to the remote queue of Websphere MQ 7 on box-1 and on box-2 we would be creating a resource adapter which would be using wmq.jmsra.rar to communicate with Websphere MQ having the queue on box-1. Using the same resource adapter and Websphere MQ’s hostName, port, queueManager, destination and transportType in the MDB we would be able to consume message from box-2 easily.

In Box-1 (10.10.10.10)

Lets say you have your Websphere MQ 7 running in this box and you can configure the remote queue in MQ 7 by following the steps given in the below article

Steps to Create A Remote Queue in WebSphere MQ 7

In Box-2 (20.20.20.20)

Below are the steps to consume messages from WebShere MQ using a MDB deployed on JBoss AS 7.1.1 final and we would be using the “standalone-full.xml”

  1. In “standalone-full.xml” following things has to be done
    1. Need to add the resource adapter under subsystem
    2. Replace

       <subsystem xmlns="urn:jboss:domain:resource-adapters:1.0"/>
      

      With

      <subsystem xmlns="urn:jboss:domain:resource-adapters:1.0">
      	<resource-adapters>
      		<resource-adapter>
      			<archive>
      				wmq.jmsra.rar
      			</archive>
      		</resource-adapter>
      	</resource-adapters>
      </subsystem>
      
    3. Need to add the resource adapter reference under mdb
    4. Replace

      <mdb>
      	<resource-adapter-ref resource-adapter-name="hornetq-ra"/>
      	<bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
      </mdb>
      

      With

      <mdb>
      	<resource-adapter-ref resource-adapter-name="wmq.jmsra.rar"/>
      	<bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
      </mdb>
      
  2. Deploy “wmq.jmsra.rar” in the “/jboss-as-7.1.1.Final/standalone/deployments/” folder
  3. We would create a MDB now having the following ActivationConfigProperty and ResourceAdapter, which has to be kept “MDB_30.jar” file in the “/jboss-as-7.1.1.Final/standalone/deployments/” folder
    1. Create a folder called “MDB_30.jar
    2. Inside “MDB_30.jar” create a “MyMDB.java” file and update this file with the below details
    3. import javax.ejb.*;
      import javax.jms.Message;
      import javax.jms.TextMessage;
      import javax.jms.JMSException;
      import javax.ejb.MessageDriven;
      import javax.jms.MessageListener;
      import javax.ejb.ActivationConfigProperty;
      import org.jboss.ejb3.annotation.ResourceAdapter;
      
      @MessageDriven( name="MyMDB",
              activationConfig = 
              { 
                  @ActivationConfigProperty(propertyName = "destinationType",propertyValue = "javax.jms.Queue"),
                  @ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "false"),
                  @ActivationConfigProperty(propertyName = "hostName", propertyValue = "MQ.HOST.NAME"),
                  @ActivationConfigProperty(propertyName = "port", propertyValue = "MQ.PORT"),
                  @ActivationConfigProperty(propertyName = "channel", propertyValue = "MQ.CHANNEL.NAME"),
                  @ActivationConfigProperty(propertyName = "queueManager", propertyValue = "MQ.QUEUE.MANAGER"),
                  @ActivationConfigProperty(propertyName = "destination", propertyValue = "MQ.QUEUE.NAME"),
                  @ActivationConfigProperty(propertyName = "transportType", propertyValue = "MQ.CLIENT")
              }) 
      @ResourceAdapter(value = "wmq.jmsra.rar")
      @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
      
      public class MyMDB implements MessageListener{
      
          public void onMessage(Message message) {
              TextMessage textMessage = (TextMessage) message;
              try {
                  System.out.println("nnt Message Received by MDB : "+ textMessage.getText());
              } catch (JMSException e) {
                  e.printStackTrace();
              }
          }
      }
      
    4. Once every thing has been put at its place, then you compile the MyMDB.java code and if you want then you can also create an JAR archive file for above folder

After following the above given steps, we have successfully configured all the setting from JBoss end. Now its time to test our configuration by following the below steps.

Testing

  1. Create a Directory somewhere in your file system like: “/urs/JBoss/Queue” to write the QueueSend.java and as we have an MDB we would not need a QueueReceive.java programs.
  2. In QueueSend.java copy the below program
    import java.io.*;
    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="com.ibm.mq.jms.context.WMQInitialContextFactory";
    
    //*************** Connection Factory JNDI name *************************
    public final static String JMS_FACTORY="MyRemoteMQMgr"; 
    
    //*************** Queue Factory JNDI name *************************
    public final static String QUEUE="MyRemoteQueue";
    
    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 URL");
    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("<Msg_Sender> ");
    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. Now open just 1 – command prompt and run the “. ./setMQ_CLASSPATH.sh” by adding two DOTs separated by a single space, in both the prompts to set the Environment (PATH & CLASSPATH).
  4. Note: You would need the following jar files from Websphere MQ side to run the above program, hence change the path given in the below script under MQ_LIB

    1. dhbcore.jar
    2. mqcontext.jar
    3. com.ibm.mq.jar
    4. com.ibm.mqjms.jar
    5. com.ibm.mq.pcf.jar
    6. com.ibm.mq.jmqi.jar
    7. com.ibm.mq.headers.jar
    8. com.ibm.mq.commonservices.jar

    setMQ_CLASSPATH.sh

    #!/bin/sh
    
    echo "Exporting CLASSPATH for IBM MQ...."
    
    MQ_LIB=/home/urs/Remote_MQ/lib
    
    export CLASSPATH=$CLASSPATH:$MQ_LIB/com.ibm.mq.commonservices.jar:$MQ_LIB/com.ibm.mq.headers.jar:$MQ_LIB/com.ibm.mq.jmqi.jar:$MQ_LIB/com.ibm.mq.pcf.jar:$MQ_LIB/com.ibm.mqjms.jar:$MQ_LIB/dhbcore.jar:$MQ_LIB/mqcontext.jar:$MQ_LIB/com.ibm.mq.jar:.:
    echo "====================================="
    echo "CLASSPATH =" $CLASSPATH
    echo "====================================="
    
  5. Then compile the QueueSend.java programs.
  6. Now run the code with the following command
  7. Prompt-1

    java QueueSend 10.10.10.10:1415/MyRemoteChannel
     

Once everything is up and running properly you just have to send around few messages in “Prompt-1” and you would notice that those messages would be shown in shell on which the standalone-full is running which is on Box-2. Hence when you are sending a messages to the Websphere MQ 7 queue which is on Box-1 the same messages are been consumed by the MDB which is been deployed on standalone-full shell is running on Box-2.


How to connect to a remote queue in JBoss AS 7 ?

Today one of our subscriber ziggy asked us using comment if we had any article which would show how to connect to a remote queue in JBoss AS7, hence we created this article which would help ziggy as well as others people also. Earlier versions of JBoss AS 7 where not having an inbuilt ability to connect to a queue remotely which was a huge concern given by the community people and users of JBoss. Hence the JBoss team took all the feedback given to them and have come up with a new version JBoss AS 7.1 Final which has an inbuilt ability to connect to a queue remotely and that too with security enabled by default. We personally are really thankful to the whole team members of JBoss AS 7 for putting this feature in the latest version of JBoss AS .

So in this article we will see how can one send messages from Box-2 [i.e. with IP 20.20.20.20] to a queue which is on the Box-1 [i.e. with IP 10.10.10.10] and those messages can be received by the receiver from the same box which is Box-1using a standalone JAVA code for sending and receiving messages. However you can also do vica-versa, which is sending messages to the queue on the same box and receive those messages from a remote box the steps remain same just the standalone JAVA code for sending and receiving messages would switch there places.

Things to remember

  • You should have the “/jboss-as-7.1.0.Final/bin/client/jboss-client-7.1.0.Final.jar” in the CLASSPATH of the client.
  • The URL would be as below, where 4447 is the remote port
  •  remote://<IP_ADDRESS>:4447
    
  • Also you need to create a user for “Application User” using the “/jboss-as-7.1.0.Final/bin/add-user.sh” which would be used for getting the connection with the JBoss on remote box
  • Last thing you would have to add the below code with the username and password created by the above step, for getting the Initial context factory as by default the remote connector is secured.
//*************** Creating Queue Connection using the UserName & Password *************************
qcon = qconFactory.createQueueConnection("USERNAME","PASSWORD");
.
.
//*************** UserName & Password for the Initial Context for JNDI lookup *************************
env.put(Context.SECURITY_PRINCIPAL, "USERNAME");
env.put(Context.SECURITY_CREDENTIALS, "PASSWORD");

In Box-1 [10.10.10.10]

Lets say we have our JBoss AS 7.1 Final in this box and we would be using standalone-full.xml for this article.

  1. Now we would create a queue called TestQ for which we would have to copy the below snip code in standalone-full.xml file inside jms-destinations tag. However you can even create the same queue from the console as well
  2. Console path:

    Profile => (+) Messaging =>  Messaging Provider => default (view ->) => JMS Destination

    Under Destination as Queue click on “Add” Button and enter the following details

    Or else can update the below xml file with the given snip-code

    standalone-full.xml

    .
    .
    <jms-destinations>
                        <jms-queue name="TestQ">
                            <entry name="java:jboss/exported/TestQ"/>
                            <durable>false</durable>
                        </jms-queue>
    .
    .
    

    Note: You would have to make sure you give “java:jboss/exported/” before giving the JNDI name of the queue in the name of “entry” attribute or else you would see the following error

    java QueueSend remote://10.10.10.10:4447
    Mar 3, 2012 6:24:29 PM org.xnio.Xnio
    INFO: XNIO Version 3.0.3.GA
    Mar 3, 2012 6:24:29 PM org.xnio.nio.NioXnio
    INFO: XNIO NIO Implementation Version 3.0.3.GA
    Mar 3, 2012 6:24:29 PM org.jboss.remoting3.EndpointImpl
    INFO: JBoss Remoting version 3.2.2.GA
    Exception in thread "main" javax.naming.NameNotFoundException: TestQ -- service jboss.naming.context.java.jboss.exported.TestQ
    	at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:97)
    	at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:177)
    	at org.jboss.naming.remote.protocol.v1.Protocol$1.handleServerMessage(Protocol.java:124)
    	at org.jboss.naming.remote.protocol.v1.RemoteNamingServerV1$MessageReciever$1.run(RemoteNamingServerV1.java:70)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    	at java.lang.Thread.run(Thread.java:662)
    
    
  3. Now we need to create a new Application User by running “${JBOSS_HOME}/bin/add-user.sh” script as following :
  4. [userone@localhost bin]$ ./add-user.sh
    
    What type of user do you wish to add?
     a) Management User (mgmt-users.properties)
     b) Application User (application-users.properties)
    (a): b
    
    Enter the details of the new user to add.
    Realm (ApplicationRealm) :  ApplicationRealm
    Username : testuser
    Password : testpassword
    Re-enter Password : testpassword
    
    What roles do you want this user to belong to? (Please enter a comma separated list, or leave blank for none) : testrole
    About to add user 'testuser' for realm 'ApplicationRealm'
    
    Is this correct yes/no? yes
    
    Added user 'testuser' to file '/home/userone/jboss-as-7.1.0.Final/standalone/configuration/application-users.properties'
    Added user 'testuser' to file '/home/userone/jboss-as-7.1.0.Final/domain/configuration/application-users.properties'
    Added user 'testuser' with roles testrole to file '/home/userone/jboss-as-7.1.0.Final/standalone/configuration/application-roles.properties'
    Added user 'testuser' with roles testrole to file '/home/userone/jboss-as-7.1.0.Final/domain/configuration/application-roles.properties'
    

    Updated: Thanks to “michaelbini”

    Note: You would have to make sure you add the new role which we just created “testrole” should be added in the “security-setting” inside “standalone-full.xml” becasue by default all the queues are only having “guest” as role, which has the permission to send and receive messages, however the new user which we made is under “testrole” role and not “guest”, hence we need to add it or else you would see the following error

    Exception in thread "main" javax.jms.JMSSecurityException: User: testuser doesn't have permission='SEND' on address jms.queue.TestQ
    	at org.hornetq.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:312)
    	at org.hornetq.core.client.impl.ClientProducerImpl.doSend(ClientProducerImpl.java:287)
    	at org.hornetq.core.client.impl.ClientProducerImpl.send(ClientProducerImpl.java:142)
    	at org.hornetq.jms.client.HornetQMessageProducer.doSend(HornetQMessageProducer.java:451)
    	at org.hornetq.jms.client.HornetQMessageProducer.send(HornetQMessageProducer.java:199)
    

    standalone-full.xml:

    Before:

    <security-settings>
      <security-setting match="#">
         <permission type="send" roles="guest"/>
         <permission type="consume" roles="guest"/>
         .
         . 
      </security-setting>
    </security-settings>
    

    After:

    <security-settings>
      <security-setting match="#">
         <permission type="send" roles="guest testrole"/>
         <permission type="consume" roles="guest testrole"/>
         .
         .
      </security-setting>
    </security-settings>
    
  5. Once the queue and application user has been created you can start you JBoss AS 7.1 final by using the following command to let it start using the IP address of the box on which it is running and in this example its 10.10.10.10
  6. bin]$ ./standalone.sh -c standalone-full.xml
     -Djboss.bind.address=10.10.10.10
    
  7. Create a directory somewhere in your file system like: “/urs/JBoss/HornetQ/Queue” to write the QueueReceive.java programs as shown below.
  8. 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="org.jboss.naming.remote.client.InitialContextFactory";
    
    //*************** Using the RemoteConnectionFactory JNDI name *************************
    public final static String JMS_FACTORY="jms/RemoteConnectionFactory";
    
    //*************** Created Queue's JNDI name *************************
    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 "+ 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);
    
    //*************** Creating Queue Connection using the UserName & Password *************************
    qcon = qconFactory.createQueueConnection("testuser","testpassword");			//<------------- Change the UserName & Password
    
    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 URL");
    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);
    
    //*************** UserName & Password for the Initial Context for JNDI lookup *************************
    env.put(Context.SECURITY_PRINCIPAL, "testuser");
    env.put(Context.SECURITY_CREDENTIALS, "testpassword");
    
    return new InitialContext(env);
    }
    }
    

In Box-2 [20.20.20.20]

Now in this box we just need to keep the QueueSend, hence again create a directory somewhere in your file system like: “/urs/JBoss/HornetQ/Queue” to write the QueueSend.java programs as shown below.

QueueSend.java

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="org.jboss.naming.remote.client.InitialContextFactory";

//*************** Connection Factory JNDI name *************************
public final static String JMS_FACTORY="jms/RemoteConnectionFactory";

//*************** Queue Factory JNDI name *************************
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);

//*************** Creating Queue Connection using the UserName & Password *************************
qcon = qconFactory.createQueueConnection("testuser","testpassword");   			//<------------- Change the UserName & Password

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 URL");
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("<Msg_Sender> ");
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);

//*************** UserName & Password for the Initial Context for JNDI lookup *************************
env.put(Context.SECURITY_PRINCIPAL, "testuser");
env.put(Context.SECURITY_CREDENTIALS, "testpassword");

return new InitialContext(env);
}
}

After following the above given steps, we have successfully configured all the setting. Now its time to test our configuration by following the below steps.

Testing

  1. Now open 1– command prompt on each boxes and run the “. ./setJBossEnv.sh” by adding two DOTs separated by a single space, in both the prompts to set the Environment (PATH & CLASSPATH).
  2. setJBossEnv.sh

    #!/bin/sh
    echo "Exporting JBOSS_HOME...."
    export JBOSS_HOME=/Jboss/jboss-as-7.1.0.Final/jboss-as   #<---- Change as per your environment
    echo "JBOSS_HOME Exported....!!!"
    echo ""
    echo "Exporting JAVA_HOME...."
    export JAVA_HOME=/Jdk/jdk1.6.0_21    #<---- Change as per your environment
    echo "JBOSS_HOME Exported....!!!"
    echo ""
    echo "Exporting CLASSPATH...."
    export CLASSPATH=$JBOSS_HOME/bin/client/jboss-client-7.1.0.Final.jar:$CLASSPATH:.:
    echo "CLASSPATH Exported....!!!"
    echo ""
    echo "Exporting PATH...."
    export PATH=$JAVA_HOME/bin:$PATH
    echo "PATH Exported....!!!"
    echo ""
    echo "========================================================================"
    echo "JBOSS_HOME = " $JBOSS_HOME
    echo ""
    echo "JAVA_HOME = " $JAVA_HOME
    echo ""
    echo "CLASSPATH = " $CLASSPATH
    echo ""
    echo "PATH = " $PATH
    echo "========================================================================"
    
  3. Then compile both the java codes the QueueSend.java and QueueReceive.java programs.
  4. Now run the code with the following command
  5. Prompt-1 on Box-1

    java QueueReceive remote://10.10.10.10:4447
     

    Prompt-2 on Box-2

    java QueueSend remote://10.10.10.10:4447
     

Once everything is up and running properly you just have to send around few messages in “Prompt-2” which is on Box-2 and you would notice that those messages would be shown in “Prompt-1” which is running which is on Box-1.

Hence our configuration worked and we are now able to connect to a remote queue in JBoss AS 7.1 Final version, now you can put the sender or receiver to any other box and follow the same steps which would work just fine.

– Should have the “/jboss-as-7.1.0.Final/bin/client/jboss-client-7.1.0.Final.jar” in the CLASSPATH of the client.
– The URL would be   URL =  remote://<IP_ADDRESS>:4447   (i.e. 4447 is the remote port)
– Also you need to create a user for “Application User” using the “/jboss-as-7.1.0.Final/bin/add-user.sh” which would be used for getting the connection with the JBoss on remote box
– IMP = you would have to add the below code with the username and password created by the above step, for getting the Initial context factory as by default the remoting connector is secured.//*************** Creating Queue Connection using the UserName & Password *************************
qcon = qconFactory.createQueueConnection(“USERNAME”,”PASSWORD”); 

//*************** UserName & Password for the Initial Context for JNDI lookup *************************
env.put(Context.SECURITY_PRINCIPAL, “USERNAME”);
env.put(Context.SECURITY_CREDENTIALS, “PASSWORD”);


How to create a Topic in JBoss AS 7 ?

In this article we would show how to create a Topic in JBoss AS7 which uses HornetQ, in this example we would use CLI command to create a Topic as well to deploy an EAR file which would consists of both a message sender as well as an MDB which would work as the consumer to consume the messages by the sender code.

We would be using the standalone mode for this article and in JBoss AS 7.1.0.CR1 version we have a different xml file called standalone-full.xml which has the all the HornetQ related configuration, but it has been said that the same would be integrated in the standalone.xml file in coming JBoss AS 7.1 version.

Before creating a Topic lets create an MDB and a Topic sender program which would be used to send and receive the messages.

Steps to create an MDB & Topic Sender

  1. Create a folder called MDB-3.
  2. In “MDB-3” folder create three folders called MDB3.jar, META-INF, TopicSender.war
  3. In “MDB3.jar” folder create MyMDB.java file and copy the below code in it and compile it as well.
  4. import javax.jms.Message;
    import javax.jms.TextMessage;
    import javax.jms.JMSException;
    import javax.jms.MessageListener;
    import javax.ejb.MessageDriven;
    import javax.ejb.ActivationConfigProperty;
    
    @MessageDriven(activationConfig =
            {
            @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"),
            @ActivationConfigProperty(propertyName="destination", propertyValue="topic/MyTopic"),
            //************************* RECONNECT PARAMERTERS  *****************************
            @ActivationConfigProperty(propertyName="reconnectAttempts", propertyValue="60"),
            @ActivationConfigProperty(propertyName="reconnectInterval", propertyValue="10")
            })
    public class MyMDB implements MessageListener{
        public void onMessage(Message message) {
            TextMessage textMessage = (TextMessage) message;
            try {
                System.out.println("===> MyMDB Received: "+ textMessage.getText());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
    
  5. In “META-INF” folder create application.xml file and copy the below code in it.
  6. <?xml version="1.0" encoding="UTF-8"?>
    <application version="5" xmlns="http://java.sun.com/xml/ns/javaee"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd">
       <module>
           <ejb>MDB3.jar</ejb>
       </module>
       <module>
    	<web>
    	   <web-uri>TopicSender.war</web-uri>
    	   <context-root>TopicSender</context-root>
    	</web>
       </module>
    </application>
    
  7. In “TopicSender.war” folder create WEB-INF folder which has classes folder and web.xml inside it and copy the below code in “web.xml”.
  8. <web-app>
    <servlet>
    	<servlet-name>TopicSenderServlet</servlet-name>
    	<servlet-class>TopicSenderServlet</servlet-class>
    	<load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    	<servlet-name>TopicSenderServlet</servlet-name>
    	<url-pattern>/TopicSenderServlet</url-pattern>
    </servlet-mapping>
    </web-app>
    
  9. Then In “classes” folder create TopicSenderServlet.java file and copy the below code in it and compile it as well
  10. import java.io.*;
    import java.util.*;
    import javax.jms.*;
    import javax.naming.*;
    import javax.transaction.*;
    import javax.servlet.http.*;
    import javax.rmi.PortableRemoteObject;
    import javax.servlet.ServletException;
    
    public class TopicSenderServlet extends HttpServlet 
    {
    	static PrintWriter out;
    	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    	{
    		try
    		{
    			out=response.getWriter();
    			InitialContext ic = getInitialContext();
    			init(ic, TOPIC_NAME);
    			sendMsg(this);
    		}
    		catch(Exception e)
    		{
    			e.printStackTrace();
    		}	
    	}
    	
    	//*************** Connection Factory JNDI name *************************
    	public final static String CONN_FACTORY="/ConnectionFactory";
    	//*************** Topic JNDI name *************************
    	public final static String TOPIC_NAME="topic/MyTopic";
    	
    	protected TopicConnectionFactory tconFactory;
    	protected TopicConnection tcon;
    	protected TopicSession tsession;
    	protected static TopicPublisher tpublisher;
    	protected Topic topic;
    	protected static TextMessage msg;
    
    	public void init(Context ctx, String topicName) throws NamingException, JMSException
    	{
    		tconFactory = (TopicConnectionFactory) PortableRemoteObject.narrow(ctx.lookup(CONN_FACTORY),TopicConnectionFactory.class);
    		tcon = tconFactory.createTopicConnection();
    		tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    		topic = (Topic) PortableRemoteObject.narrow(ctx.lookup(topicName), Topic.class);
    		tpublisher = tsession.createPublisher(topic);
    		msg = tsession.createTextMessage();
    		tcon.start();
    	}
    
    	private static void sendMsg(TopicSenderServlet ts) throws IOException, JMSException
    	{
    		boolean readFlag=true;
    		out.println("<HTML>");
    		out.println("<BODY>");
    		out.println("<CENTER>");
    		out.println("<H1>Topic Sender Servlet</H1>");
    		out.println("Following Messages has been sent !!!<br>");
    		out.println("====================================");
    		for(int j=1;j<=3;j++) 
    		{
            		msg.setText(""+j); 		// Messages 
            		tpublisher.publish(msg); 	// Messages sent
       			out.println("<BR>Message Sent = "+j);
    		}
    		out.println("<BR>====================================");
    		out.println("</CENTER>");
    		out.println("</BODY>");
    		out.println("</HTML>");
    	}
    
    	private static InitialContext getInitialContext() throws NamingException
    	{
    		return new InitialContext();
    	}
    }
    
  11. Once you have done with all this you now just have to create an EAR file out of this, for that you need to be in the MDB-3 folder and run the below command (make sure you have setted the java/bin in your PATH). Note: you would have to give the (.) dot at last as well
  12. MDB-3] jar -cvf MDB-3.ear .
    

Steps for creating a Topic in JBoss AS 7

  1. Now we would have to start our JBoss AS 7 with standalone-full.xml using -c parameter during the start-up of JBoss
  2. bin] ./standalone.sh -c standalone-full.xml
    
  3. Once the JBoss server is up and running properly then you can run the below CLI command with using the a Topic-setup.cli file which would make sure that a new Topic MyTopic is been created and it would also deploy the MDB-3.ear to the server.
  4. Create a file called Topic-setup.cli in the bin folder of JBoss and copy the below content

    connect
    add-jms-topic --name=MyTopic --entries=topic/MyTopic
    deploy /home/urs/JMS/MDB-3/MDB-3.ear
    

    Run the below command

    bin] ./jboss-admin.sh --file=Topic-setup.cli
    

Testing


Once you can successfully created a Topic and deployed the application using the above CLI command now its time for testing our newly created Topic

  1. Open a browser and hit the below URL (I am supposing that you are running JBoss on default port and IP) and that would send 3 messages to the Topic which can be seen on the browser itself
  2. http://localhost:8080/TopicSender/TopicSenderServlet
    

  3. After hitting the above URL you would see the below messages been received by the MDB on the running JBoss server prompt
  4. 14:32:48,295 INFO  [stdout] (Thread-1 (group:HornetQ-client-global-threads-1623557144)) ===> MyMDB Received: 1
    14:32:48,295 INFO  [stdout] (Thread-0 (group:HornetQ-client-global-threads-1623557144)) ===> MyMDB Received: 2
    14:32:48,296 INFO  [stdout] (Thread-2 (group:HornetQ-client-global-threads-1623557144)) ===> MyMDB Received: 3
    

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