Java Messaging Service (JMS) with JBoss 7.1.1 Final

1. Introduction – JMS

This is an application interface for sending the messages between the users or the clients created on Java platform.

Following diagram illustrates basic idea behind JMS.Image

Message Producer and Consumer application can run on separate machines and all they have to know to communicate is the URL of the JMS Provider.

What is JMS Provider ?
Provider can be JEE  Server. Eg: WebLogic, JBoss, GlassFish Server, Apache Active MQ Server

Technical Terms use in Java Message Service

JMS provider :-
An implementation of the JMS interface for a Message Oriented Middleware (MOM). Providers are implemented as either a Java JMS implementation or an adapter to a non-Java MOM.

JMS client:- An application or process that produces and/or receives messages.

JMS producer/publisher:-  A JMS client that creates and sends messages.

JMS consumer/subscriber:-
A JMS client that receives messages.

JMS message:-
An object that contains the data being transferred between JMS clients.

JMS queue:-
A staging area that contains messages that have been sent and are waiting to be read. Note that, contrary to what the name queue suggests, messages have to be delivered in the order sent A JMS queue only guarantees that each message is processed only once.

JMS topic :- A distribution mechanism for publishing messages that are delivered to multiple subscribers.

Queue VS Topic

Queue:-
Point-to-point model
Only one consumer gets the message
Messages have to be delivered in the order sent

Topic:-

Publish/subscribe model
Multiple clients subscribe to the message
There is no guarantee messages have to be delivered in the order sent

Type of Messages- Message Interfaces

Message Interface Body Content
javax.jms.BytesMessage array of bytes
javax.jms.MapMessage key-value pairs
javax.jms.ObjectMessage serialized Java object
javax.jms.StreamMessage stream of Java primitive values
javax.jms.TextMessage Java String object

Message Header Properties
The message headers are used to provide information for message processing.

Header Field (Meta Data) Description
JMSCorrelationID links one message to another
JMSDeliveryMode javax.jms.DeliveryMode.NON_PERSISTENT or javax.jms.DeliveryMode.PERSISTENT
JMSDestination Topic or Queue this message is bound for
JMSExpiration expiration value (default is never)
JMSMessageID message ID
JMSPriority priority level (default is 4)
JMSRedelivered is message being redelivered
JMSReplyTo Topic or Queue where a reply should be sent
JMSTimestamp message timestamp
JMSType message type supplied by client

JMS Messaging with JBoss 7.1.1

1.Start  Jboss server with JMS Features Visibility

<JBoss Home>/bin>sh standalone.sh –server-config=/standalone-full.xml

2.How to configure Queue or Topic in JBoss server.

i. Open standalone-full.xml inside <JBoss Home>/standalone/configuration
ii.  Go to   <jms-destinations> Tag
iii. Add Queue or Topic Entry.

Eg:

  <jms-destinations>
                    <jms-queue name=”testQueue”>
                        <entry name=”queue/test”/>
                        <entry name=”java:jboss/exported/jms/queue/test”/>
                    </jms-queue>
                    <jms-topic name=”testTopic”>
                        <entry name=”topic/test”/>
                        <entry name=”java:jboss/exported/jms/topic/test”/>
                    </jms-topic>
        </jms-destinations>

3. Sample JEE Application for adding  Text Data to a JMS Queue.

Steps:
Create JMS Client Program to sends Messge to JMS Provider. Here JMS Provider is JBoss Server.

Java Servlet use as JMS clent. (Producer)
Data is adding to   “testQueue

Code :

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/JMSClientServlet")
public class JMSClientServlet extends HttpServlet {

    Context ic = null;

    ConnectionFactory cf = null;

    Connection connection = null;

    /**
 *
 */
    public void init() throws ServletException {

        try {
            ic = new InitialContext();
            cf = (ConnectionFactory) ic.lookup("/ConnectionFactory");

        } catch (NamingException e) {

            e.printStackTrace();
        }
    }

    /**
     *
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String destinationName = "java:/queue/test";
        PrintWriter out = response.getWriter();

        try {

            connection = cf.createConnection();

            Queue queue = (Queue) ic.lookup(destinationName);

            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer publisher = session.createProducer(queue);

            connection.start();
            TextMessage message = session.createTextMessage(request.getParameter("message"));
            // publish the message to the defined Queue
            publisher.send(message);

            out.println("---------Message sent to  the JMS Provider--------");

        } catch (Exception exc) {
            exc.printStackTrace();
        } finally {

            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request, response);
    }

}

Message Consumer Code Sample.
Here Message Driven Bean (MDB) is the Consumer.

package com.mdb;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

/**
 * Message-Driven Bean implementation class for: MDBSample- This is for Consume the Queue
 */
@MessageDriven(activationConfig = {@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/queue/test"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})
public class MessegeConsumer implements MessageListener {

    /**
     * Default constructor.
     */
    public MessegeConsumer() {

    }

    /**
     * @see MessageListener#onMessage(Message)
     */
    public void onMessage(Message message) {

        TextMessage tm = (TextMessage) message;
        try {
            System.out.println("Received message is ==========> " + tm.getText());
        } catch (JMSException e) {

            e.printStackTrace();
        }

    }

}

4. Managing and Viewing JMS Queue Data.

How to Acess the Data of JMS Queue Remotly?

We can use JMX Interface with the help of Mbean to acess the Queue Data.
Queue Meta Data can be access using JMX.

Follwing is Client Application code for acessing Queue Data remotly.

package com.remote;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.hornetq.api.core.management.ObjectNameBuilder;
import org.hornetq.api.jms.management.JMSQueueControl;

public class RemoteJMXClient {

    /**
     * @param args
     * @throws IOException
     * @throws MalformedURLException
     */
    public static void main(String[] args) throws MalformedURLException, IOException {

        // NOTE : standalone-full.xml configuration
        // Enabled - <jmx-management-enabled>true</jmx-management-enabled>
        String urlString = "service:jmx:remoting-jmx://localhost:9999";
        JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(urlString), new HashMap<String, String>());

        try {

            MBeanServerConnection mbsc = connector.getMBeanServerConnection();
            ObjectName on = ObjectNameBuilder.DEFAULT.getJMSQueueObjectName("testQueue");

            JMSQueueControl jmsqserverControl =
                (JMSQueueControl) MBeanServerInvocationHandler.newProxyInstance(mbsc, on, JMSQueueControl.class, false);

            Map<String, Object>[] messages = jmsqserverControl.listMessages(null);
            System.out.println("Added Message Count------>" + jmsqserverControl.getMessagesAdded());
            System.out.println("Consumed Message Count--->" + jmsqserverControl.getConsumerCount());

            for (Map<String, Object> map : messages) {

                System.out.println("Message Id-------->" + map.get("JMSMessageID"));
                System.out.println("Message Address--->" + map.get("address"));

            }
        } catch (Throwable e) {

            System.out.println("Exception : " + e);

        } finally {

            connector.close();
            System.out.println("The end");

        }

    }

}

Note : There is a limitation of viewing Queue body using JMX.
Following is a remote JMS Client to acess JMS Queue body.

Do the following steps before execute the code.
Create Application user and use Application users login data in the code.
Set the “guest” Access rights when creating Application user. (guest has Queue consume rights by default.)

package com.remote;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Enumeration;
import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * Accessing Remotly-JMS Queue
 */

public class RemoteJMSClient {

    private static final String PASSWORD = "password";

    private static final String APPICATION_USER_NAME = "bandu";

    private static final String JMS_QUEUE_JNDI_NAME = "jms/queue/test";

    public static void main(String[] args) throws MalformedURLException, IOException, NamingException, JMSException {

        final Properties env = new Properties();

        env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        env.put(Context.PROVIDER_URL, "remote://localhost:4447");
        env.put(Context.SECURITY_PRINCIPAL, APPICATION_USER_NAME);
        env.put(Context.SECURITY_CREDENTIALS, PASSWORD);
        Context context = new InitialContext(env);

        ConnectionFactory cf = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");
        Queue queue = (Queue) context.lookup(JMS_QUEUE_JNDI_NAME);
        Connection connection = cf.createConnection(APPICATION_USER_NAME, PASSWORD);// NOTE: role should be guest when
                                                                                    // creating application user
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        QueueBrowser browser = session.createBrowser(queue);

        Enumeration messageEnum = browser.getEnumeration();
        while (messageEnum.hasMoreElements()) {
            TextMessage message = (TextMessage) messageEnum.nextElement();
            System.out.println("Queue Message---------------->: " + message.getText());
            System.out.println("JMSCorrelation ID------------>: " + message.getJMSCorrelationID());
            System.out.println("Message ID ------------------>: " + message.getJMSMessageID());

        }

    }

}

JMS Sample Project JMSRemoteClientProject.zip

This project covers following areas.

1. JMS Client (JMX and JMS)
RemoteJMXClient.java
JMSClientOutQueue.java

2. Adding  Data to known Queue in remote server and Get the processed response via known queue.

JMSClientInQueueLoadProviderFactory.java
RemoteAsynchronousQueueListner.java

3. Adding and Reading data is done from Test Class
JMSSampleScenarioTest.java
JMS Presentation(1)

JMS Presentation

Thanks.

Advertisements
Tagged with: , , , , , , , ,
Posted in Uncategorized
14 comments on “Java Messaging Service (JMS) with JBoss 7.1.1 Final
  1. Dhammika says:

    Good tutorial , helped me to understand the basics of JMS as a beginner …! Thanks !

  2. Disney says:

    Excellaent work……… This helped me a lot…….

  3. Lankesh says:

    Cheers !! It helped me a lot Thanks.

  4. anjanakulasinghe says:

    Nice post.. You saved hours of google search.. This is exactly what i was looking for.. (y)

  5. Niranjan Aburadha says:

    great article. It will helpful for me in future

  6. ABKRT says:

    Great article, thank you for posting…

  7. Manjula says:

    Great article.

  8. kasun11 says:

    Excellent.. nice work (y)

  9. THilina says:

    Good article, This helped me a lot..

  10. Thanks for the explanation and sample code! Thanks a lot!

  11. zura says:

    Very good and helpful article. I can’t download source code, I’m getting 404 error when click on the link above.

    http://www.upfordown.com/public/pdownload/126510/JMSRemoteClientProject.zip

    Can you attach file? or send me this file? it is my mail zurikacitadze@gmail.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: