Jms – Produce and consume messages

In this post I’ll describe how produce and consume Jms message over Broker MessageQueue service. I’ve found it a very useful channel transport and I think it should have had more spaces on internet articles.

It’s a very powerfull and quite easy-to-use. So, why don’t use it?

I’ve seen a large amount of files exchange a lot of time to the aim of sharing information between different systems. I think it’s very old method and Message Queue most useful for this scope.

I splitted this post in two part. They are produce and consume message. I used Sun MessageQueue for Broker but the solution it’s not linked with the broker type.

Let’s start with the first part.

Produce

The target is to put a Message of type “Order” into a Queue “OrderQueue” to the broker.

This is the producer Main class.

package it.samplejms;
import it.samplejms.bean.Order;
import java.math.BigDecimal;
import java.util.Date;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.naming.NamingException;
public class Producer {
 /**
  * @param args
  * @throws NamingException
  * @throws JMSException
  */
 public static void main(String[] args) throws NamingException, JMSException {
  
  Order order = new Order(123, new BigDecimal(2300), 120, new Date());
  
  FacadeJms.createJms();
        MessageProducer producer = FacadeJms.getSession().createProducer(FacadeJms.getDestination());
       
        Message m = FacadeJms.getSession().createObjectMessage(order);
        producer.send(m);
       
        producer.close();
       
        FacadeJms.CloseJms();
 }
}

But, most important class of the project (for us) it’s FacadeJms!

package it.samplejms;
import java.util.Hashtable;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class FacadeJms {
 
 private static Session session;
 private static Destination destination;
 private static Connection connection;
 
 protected static void createJms() throws NamingException, JMSException
 {
        Hashtable properties = new Hashtable();
        properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
        properties.put(Context.PROVIDER_URL, file:///store1/admobjstore");
        Context context = new InitialContext(properties);
       
        ConnectionFactory factory = (ConnectionFactory) context.lookup("ConnectionFactory");
       
        destination = (Destination) context.lookup("OrderQueue");
       
        connection = factory.createConnection();
        session = getConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
 }
 public static Session getSession() {
  return session;
 }
 public static Destination getDestination() {
  return destination;
 }
 
 public static void CloseJms() throws JMSException
 {
   session.close();
   getConnection().close();
 }
 public static Connection getConnection() {
  return connection;
 }
}

The steps are:

  • Get a Context and Destination lookup from ConnectionFactory;
  • Get  Connection;
  • Get Session.

In Main class I created the producer and the Message from Order object. Then I send the message and I close all objects.

Now, you message is into the queue.

Consumer

The target is to read the message from the queue and print it on screen.

This is the consumer main class.

package it.matrix.samplejms;
import it.matrix.samplejms.bean.Order;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.ObjectMessage;
import javax.naming.NamingException;
public class Consumer {
 /**
  * @param args
  * @throws NamingException
  * @throws JMSException
  */
  public static void main(String[] args) throws NamingException, JMSException {

    FacadeJms.createJms();

    MessageConsumer consumer = FacadeJms.getSession().createConsumer(FacadeJms.getDestination());
    FacadeJms.getConnection().start();

    Message msg = consumer.receive();
    Order order = (Order)((ObjectMessage) msg).getObject();

    System.out.println("Read Message: " + order.toString());
    consumer.close();
    FacadeJms.CloseJms();
 }
}

This is the Message transported

package it.matrix.samplejms.bean;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlAccessType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
 "orderId",
 "invoice",
 "itemNumber",
 "orderDate"
})
@XmlRootElement(name = "order")
public class Order implements Serializable{

 /**
  *
  */
 private static final long serialVersionUID = -681118734402646907L;
 /**
  *
  */
 @XmlElement(required = true)
 private int orderId;
 
 @XmlElement(required = true)
 private BigDecimal invoice;
 
 @XmlElement(required = true)
 private int itemNumber;
 
 @XmlElement(required = true)
 private Date orderDate;
 
 public Order(){}
 
 public Order(int orderId,
    BigDecimal invoice,
    int itemNumber,
    Date orderDate){
  
  this.setOrderId(orderId);
  this.setInvoice(invoice);
  this.setItemNumber(itemNumber);
  this.setOrderDate(orderDate);
 }
 
  // String Representation:
    @Override
    public String toString() {
        return "orderId: " + getOrderId() +
     " invoice: " + getInvoice().toString() +
     " itemNumber: " + getItemNumber() +
     " orderDate: " + getOrderDate().toString();
    }

 public int getOrderId() {
  return orderId;
 }

 public void setOrderId(int orderId) {
  this.orderId = orderId;
 }

 public BigDecimal getInvoice() {
  return invoice;
 }

 public void setInvoice(BigDecimal invoice) {
  this.invoice = invoice;
 }

 public int getItemNumber() {
  return itemNumber;
 }

 public void setItemNumber(int itemNumber) {
  this.itemNumber = itemNumber;
 }

 public Date getOrderDate() {
  return orderDate;
 }

 public void setOrderDate(Date orderDate) {
  this.orderDate = orderDate;
 }
}

Now it’s time to run the producer Main class. At the end, you’ll able to see, from jconsole interface, your message into the queue.

Once run the consumer, you’ll able to see “NumMsgsOut” equals with “NumMsgsIn”

And the message output is

Read Message: orderId: 123 invoice: 2300 itemNumber: 120 orderDate: Mon Jun 04 10:00:31 CEST 2012

I wish you could have found your response about the question “Why should I use Message Queue?” in this post.

More references are available over internet web sites. I think it’s a good idea spend some time to go into deep.

Advertisements

One thought on “Jms – Produce and consume messages

  1. Pingback: Spring Jms – Produce and consume messages « Tech Annotation

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