Labels

Tuesday, June 9, 2009

How to create a simple JMS application example using Netbeans and Glassfish

How to create a simple JMS application example using Netbeans and Glassfish

How to create a simple JMS application example using Netbeans 6.7 and GlassFish v2.1

Author: T.A. Nguyen
I am choosing the OLD FASHIONED example to illustrate the concept and also promote the fundamental understanding of JMS. Message Driven beans can easily be done in place of these examples.
Here are the steps:
  • Download and install Netbeans 6.5.1 or later (I use 6.7RC2 for fun)
  • Create an "Enterprise Application Client"
  • Write some codes for the MessageApplication
  • Start-up the GFv2.1
  • Use the GFv2.1 Admin Console to add a ConnectionFactory and a Destination (Queue).
  • Execute the application!

Download and Install Netbeans

Download the latest NetBeans from http://netbeans.org, make sure that you install GlassFish v2.1 as well. We will be using GFv2.1 for the JNDI and MQ services.

Create a "Enterprise Application Client"

  • File -> New Project -> Java EE -> Enterprise Application Client
  • and click [ next > ] button.
  • Project Name: MyFirstJMSQueue
  • Project Location: C:\Projects
  • and click [ next > ] button.
  • Server: GlassFish v2.1
  • Java EE Version: Java EE 5
  • Main Class: org.cnci.jms.first.MessageApp
  • click [ Finish ] button.
   

Write some codes

MessageConnection.java

In practice, I like to encapsulate the Connection, Session and other control to a single class called: MessageConnection. MessageConnection will allow us to: connect(), disconnect(), send() and receive(). Other methods such as getConnection(), getDestination(), getSession(), getConsumer(), getProducer() are extra methods that can use to give developer a finer control.
MessageConnection.ava
//**********************************************************************
//
// MessageConnection
//
//**********************************************************************
//***************************************//
// package //
//***************************************//
package org.cnci.jms.first;

//***************************************//
// imports //
//***************************************//
import javax.jms.*;
import javax.naming.*;

/***********************************************************************
* A simple facade common JMS Connection that will encapsulate and handle
* all the jms connection, session, and message transportation.
*
* @author T.A. Nguyen
* @version 1.0, Jan 1, 2005
***********************************************************************/
public class MessageConnection {

private String destinationName = "jms/myDestination";
private String factoryName = "jms/myConnectionFactory";
private Context context;
private ConnectionFactory connectionFactory;
private Connection connection;
private Session session;
private Destination destination;
private MessageConsumer messageConsumer;
private MessageProducer messageProducer;
private boolean connected = false;

/********************************************************************
* Constructor
********************************************************************/
public MessageConnection() {
}

/********************************************************************
* Attempts to connect to the JMS messaging system.
*
* @throws MessageException If a connect failure occurs.
********************************************************************/
public Context getContext() throws MessageException {
  if (context == null) {
    try {
      //-------------------------------------
      // Initialize JNDI.
      //-------------------------------------
      context = new InitialContext();
    } catch (NamingException e) {
      disconnect();
      e.printStackTrace();
      throw new MessageException("Naming Exception: " + e);
    }
  }
  return context;
}

/********************************************************************
* Attempts to connect to the JMS messaging system.
*
* @throws MessageException If a connect failure occurs.
********************************************************************/
public MessageConsumer getConsumer() throws MessageException {
  if (messageConsumer == null) {
    try {
    //-------------------------------------
    // Create a message sender.
    //-------------------------------------
      messageConsumer = getSession().createConsumer(getDestination());
      if (!connected) {
        getConnection().start();
        connected = true;
      }
    } catch (JMSException e) {
      disconnect();
      e.printStackTrace();
      throw new MessageException("JMS Create Receiver Exception: " + e);
    }
   }
   return messageConsumer;
}

/********************************************************************
* Attempts to connect to the JMS messaging system.
*
* @throws MessageException If a connect failure occurs.
********************************************************************/
public MessageProducer getProducer() throws MessageException {
  if (messageProducer == null) {
    try {
      //-------------------------------------
      // Create a message sender.
      //-------------------------------------
      messageProducer = getSession().createProducer(getDestination());
      if (!connected) {
        getConnection().start();
        connected = true;
      }
    } catch (JMSException e) {
      disconnect();
      e.printStackTrace();
      throw new MessageException("JMS Create Sender Exception: " + e);
    }
  }
  return messageProducer;
}

/********************************************************************
* Attempts to connect to the JMS messaging system.
*
* @throws MessageException If a connect failure occurs.
********************************************************************/
public ConnectionFactory getConnectionFactory() throws MessageException {
  if (connectionFactory == null) {
    try {
      //------------------------------------------
      // Lookup the connection factory using JNDI.
      //------------------------------------------
      connectionFactory = (ConnectionFactory) getContext().lookup(factoryName);
    } catch (NamingException e) {
      disconnect();
      e.printStackTrace();
      throw new MessageException("Naming Lookup Factory Exception: " + e);
    }
  }
  return connectionFactory;
}

/********************************************************************
* Attempts to connect to the JMS messaging system.
*
* @throws MessageException If a connect failure occurs.
********************************************************************/
public Connection getConnection() throws MessageException {
  if (connection == null) {
    try {
      //-------------------------------------
      // Use the connection factory to create
      // a JMS connection.
      //-------------------------------------
      connection = getConnectionFactory().createConnection();
    } catch (JMSException e) {
      disconnect();
      e.printStackTrace();
      throw new MessageException("JMS Create Queue Connection Exception: " + e);
    }
   }
   return connection;
}

/********************************************************************
* Attempts to connect to the JMS messaging system.
*
* @throws MessageException If a connect failure occurs.
********************************************************************/
public Session getSession() throws MessageException {
  if (session == null) {
    try {
      //-------------------------------------
      // Use the connection to create a
      // session.
      //-------------------------------------
      session = getConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
    } catch (JMSException e) {
      disconnect();
      e.printStackTrace();
      throw new MessageException("JMS Create Session Exception: " + e);
    }
  }
  return session;
}

/********************************************************************
* Attempts to connect to the JMS messaging system.
*
* @throws MessageException If a connect failure occurs.
********************************************************************/
public Destination getDestination() throws MessageException {
  if (destination == null) {
    try {
      //-------------------------------------
      // Lookup the destination (queue) using
      // JNDI. Note that the designated
      // destination (destinationName) must be
      // administered within the JMS service
      // environment.
      //-------------------------------------
      destination = (Destination) getContext().lookup(destinationName);
     } catch (NamingException e) {
       disconnect();
       e.printStackTrace();
       throw new MessageException("Naming Lookup Queue Exception: " + e);
     }
   }
   return destination;
}

/********************************************************************
* Attempts to disconnect from the JMS messaging system.
*
* @throws MessageException If a disconnect failure occurs.
********************************************************************/
public void connect() throws MessageException {
  // make sure a connection and a session established.
  getSession();
  if (!connected) {
    try {
      getConnection().start();
      connected = true;
    } catch (JMSException e) {
      e.printStackTrace();
      connected = false;
      disconnect();
      throw new MessageException("JMS Connection Exception: " + e);
    }
  }
}

/********************************************************************
* Attempts to disconnect from the JMS messaging system.
*
* @throws MessageException If a disconnect failure occurs.
********************************************************************/
public void disconnect() throws MessageException {
  if (connection != null) {
    try {
      connection.close();
   } catch (JMSException e) {
      e.printStackTrace();
      throw new MessageException("JMS Exception: " + e);
   }
  }

  connection = null;
  session = null;
  messageProducer = null;
  messageConsumer = null;

  connected = false;
}

/********************************************************************
* Returns true if a connection is currently established.
********************************************************************/
public boolean isConnected() {
   return connected;
}

/********************************************************************
* Returns true if a connection is currently established.
********************************************************************/
public void send(Message message) throws MessageException {
  try {
    getProducer().send(message);
  } catch (JMSException e) {
    e.printStackTrace();
    throw new MessageException("JMS Send Exception: " + e);
  }
}

/********************************************************************
* Attempts to receive a message.
*
* @throws MessageException If the receive fails.
********************************************************************/
public Message receive(int n) throws MessageException {
  Message message = null;

  try {
    message = getConsumer().receive(n);
  } catch (JMSException e) {
    e.printStackTrace();
    throw new MessageException("JMS Receive Exception: " + e);
  }
  return message;
}
}

MessageException.java

A simple Exception class representing a failure in JMS Message processing.
MessageException.ava
//**********************************************************************
//
// MessageException
//
//**********************************************************************
//***************************************//
// package //
//***************************************//
package org.cnci.jms.first;

//***************************************//
// imports //
//***************************************//
/***********************************************************************
* This class implements an exception representing a failure in
* message processing.
*
* @author T.A. Nguyen
* @version 1.0, Jan 1, 2005
***********************************************************************/
public class MessageException extends Exception {

/********************************************************************
* Constructor.
********************************************************************/
public MessageException() {
  super();
}

/********************************************************************
* Constructor.
*
* @param info Information to be sent along with the exception.
********************************************************************/
public MessageException(String info) {
  super(info);
}
}

MessageSender.java

A simple create and send message class
MessageSender.ava
//**********************************************************************
//
// MessageSender
//
//**********************************************************************
//***************************************//
// package //
//***************************************//
package org.cnci.jms.first;

//***************************************//
// imports //
//***************************************//
import javax.jms.*;

/***********************************************************************
* A simple facade for sending messages in a Point-to-Point domain.
*
* @author T.A. Nguyen
* @version 1.0, Jan 1, 2005
***********************************************************************/
public class MessageSender {
private MessageConnection messageConnection;

/********************************************************************
* Constructor
********************************************************************/
public MessageSender() {
}

/********************************************************************
* Create a MessageConnection
*
* @throws MessageException If the send fails.
********************************************************************/
private MessageConnection getMessageConnection() throws MessageException {
  if (messageConnection == null) {
    messageConnection = new MessageConnection();
  }
  return messageConnection;
}

/********************************************************************
* Attempt to get a QueueSession from the MessageConnection object.
*
* @throws MessageException If the send fails.
********************************************************************/
private Session getSession() throws MessageException {
  if (getMessageConnection() != null) {
    return getMessageConnection().getSession();
  }
  return null;
}

/********************************************************************
* Attempts to send the passed message.
*
* @throws MessageException If the send fails.
********************************************************************/
public void send(Message message) throws MessageException {
  if (message != null) {
    getMessageConnection().send(message);
  }
}

/********************************************************************
* Attempts to establish the connection.
*
* @throws MessageException If the send fails.
********************************************************************/
public void connect() throws MessageException {
  getMessageConnection().getProducer();
}

/********************************************************************
* Attempts to disconnection.
*
* @throws MessageException If the send fails.
********************************************************************/
public void disconnect() throws MessageException {
  if (messageConnection != null) {
    try {
      messageConnection.disconnect();
      messageConnection = null;
    } catch (MessageException e) {
      messageConnection = null;
      e.printStackTrace();
      throw e;
    }
  }
}

/********************************************************************
* Attempts to return a newly constructed TextMessage.
*
* @throws MessageException If the construction fails.
********************************************************************/
public TextMessage createTextMessage() throws MessageException {
  TextMessage message = null;

  try {
    message = getSession().createTextMessage();
  } catch (JMSException e) {
    throw new MessageException("JMS Create Text Message Exception: " + e);
  }
  return message;
}

/********************************************************************
* Attempts to return a newly constructed BytesMessage.
*
* @throws MessageException If the construction fails.
********************************************************************/
public BytesMessage createBytesMessage() throws MessageException {
  BytesMessage message = null;

  try {
    message = getSession().createBytesMessage();
  } catch (JMSException e) {
    throw new MessageException("JMS Create Bytes Exception: " + e);
  }
  return message;
}

/********************************************************************
* Attempts to return a newly constructed ObjectMessage.
*
* @throws MessageException If the construction fails.
********************************************************************/
public ObjectMessage createObjectMessage() throws MessageException {
  ObjectMessage message = null;

  try {
    message = getSession().createObjectMessage();
  } catch (JMSException e) {
    throw new MessageException("JMS Create Object Message Exception: " + e);
  }

  return message;
}

/********************************************************************
* Attempts to return a newly constructed MapMessage.
*
* @throws MessageException If the construction fails.
********************************************************************/
public MapMessage createMapMessage() throws MessageException {
  MapMessage message = null;

  try {
    message = getSession().createMapMessage();
  } catch (JMSException e) {
    throw new MessageException("JMS Create Map Message Exception: " + e);
  }

  return message;
}

/********************************************************************
* Attempts to return a newly constructed StreamMessage.
*
* @throws MessageException If the construction fails.
********************************************************************/
public StreamMessage createStreamMessage() throws MessageException {
  StreamMessage message = null;

  try {
    message = getSession().createStreamMessage();
  } catch (JMSException e) {
    throw new MessageException("JMS Create Stream Message Exception: " + e);
  }

  return message;
}
}

MessageReceiver.java

A simple receive and consume message class
MessageReceiver.ava
//**********************************************************************
//
// MessageReceiver
//
//**********************************************************************
//***************************************//
// package //
//***************************************//
package org.cnci.jms.first;

//***************************************//
// imports //
//***************************************//
import javax.jms.*;

/***********************************************************************
* A simple facade for receiving messages from a PTP domain.
*
* @author T.A. Nguyen
* @version 1.0, Jan 1, 2005
***********************************************************************/
public class MessageReceiver {

private MessageConnection messageConnection;

/********************************************************************
* Constructor
********************************************************************/
public MessageReceiver() {
}

private MessageConnection getMessageConnection() throws MessageException {
  if (messageConnection == null) {
    messageConnection = new MessageConnection();
  }
  return messageConnection;
}

/********************************************************************
* Attempts to receive a message.
*
* @throws MessageException If the receive fails.
********************************************************************/
public Message receive() throws MessageException {
  return getMessageConnection().receive(1);
}

public void connect() throws MessageException {
  getMessageConnection().getConsumer();
}

public void disconnect() throws MessageException {
  if (messageConnection != null) {
    try {
      messageConnection.disconnect();
      messageConnection = null;
    } catch (MessageException e) {
      messageConnection = null;
      e.printStackTrace();
      throw e;
    }
  }
}
}

MessageApp.java

A simple test application for the MessageSender and MessageReceiver classes.

MessageApp.ava
//**********************************************************************
//
// MessageApp
//
//**********************************************************************
//***************************************//
// package //
//***************************************//
package org.cnci.jms.first;

//***************************************//
// imports //
//***************************************//
import javax.jms.*;

/***********************************************************************
* This class provides a test application for the MessageSender and
* MessageReceiver classes.
*
* @author T.A. Nguyen
* @version 1.0, Jan 1, 2005
***********************************************************************/
public class MessageApp {

/********************************************************************
* Application main entry point.
********************************************************************/
public static void main(String[] args) {
  try {
    //--------------------------------
    // Establish sender and receiver
    //--------------------------------
    MessageSender sender = new MessageSender();
    sender.connect();

    MessageReceiver receiver = new MessageReceiver();
    receiver.connect();

    //--------------------------------
    // Create a text message
    //--------------------------------
    TextMessage message = sender.createTextMessage();
    message.setText("This is a test text message");

    //--------------------------------
    // Send the message
    //--------------------------------
    System.out.println("Sending message: " + message.getText());
    sender.send(message);

    //--------------------------------
    // Sleep for a few seconds
    //--------------------------------
    try {
      Thread.sleep(3 * 1000);
    } catch (InterruptedException ex) {
    }

    //--------------------------------
    // Retrieve the message
    //--------------------------------
    TextMessage receivedMessage = (TextMessage) receiver.receive();
    System.out.println("Message received: " + receivedMessage.getText());

    //--------------------------------
    // Terminate connections
    //--------------------------------
    sender.disconnect();
    receiver.disconnect();
  } catch (JMSException jmsEx) {
    System.out.println("JMS Exception: " + jmsEx);
  } catch (MessageException msgEx) {
    System.out.println("Message Exception: " + msgEx);
  }
}
}

Startup GlassFish v2.1

  • From the "Services" tab, right button on the Servers -> "GlassFish v2.1" and "Start" the server.
  • Right button again on "GlassFish v2.1" and click "View Admin Console"
  • Login to the console (admin/adminadmin is the defaul userid/password), If this is on the network, change it.
  • Choose Resources -> JMS Resources -> Connection Factories
  • Click [ New... ] to create a new JMS Connection Factory
  • JNDI Name: jms/myConnectionFactory
  • Resource Type: javax.jms.QueueConnectionFactory
  • Description: My First JMS Queue Connection Test
  • Status: Enabled (checked)
  • Click [ OK ] button
  • ----
  • Choose Resources -> JMS Resources ->Destination Resources
  • Click [ New... ] to create a new JMS Destination Resource
  • JNDI Name: jms/myDestination
  • Physical Destination Name: myDestination
  • Resource Type: javax.jms.Queue
  • Description: My First JMS Queue Test
  • Status: Enabled (checked)
  • Click [ OK ] button.
    

Execute the application:

  • Go back to the project and right button on the MessageApp.java file, then select Run File.