Simple JMS 2.0 Example within JEE7

Introduction:

Source Wikipedia (http://en.wikipedia.org/wiki/Java_Message_Service)

The Java Message Service (JMS) API is a Java Message Oriented Middleware (MOM) API for sending messages between two or more clients. JMS is a part of the Java Platform, Enterprise Edition, and is defined by a specification developed under the Java Community Process as JSR 914. It is a messaging standard that allows application components based on the Java Enterprise Edition (Java EE) to create, send, receive, and read messages. It allows the communication between different components of a distributed application to be loosely coupled, reliable, and asynchronous.

We list these JMS elements below:

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 (by only one consumer). Note that, contrary to what the name queue suggests, messages don’t have to be received in the order in which they were 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.

 

JMS 2.0

Part of JEE 7, Java Message Service 2.0 was released in May 2013, it brings to the developer the advantage to write a few number of code lines to use this technology by introducing a new elements and by supporting resource injection.
It can be used within Java EE Web or EJB applications, or in standalone java application.
Three new interfaces were introduced :

To learn more about JMS 2.0 I recommend highly to read the folowing:
Wiki Page
JSR 343
JEE DOC

 Example:

In our example we will create two stateless EJB whose first acts as producer and the second as consumer. Handled message will be simply a string pushed to a Queue. The broker will be the Glassfish Embedded broker, so no extra install is needed. all what you need is JEE 7 certified server with an IDE and a JDK (for your information I use JDK8 and Eclipse Luna 4.4.1 )

both of these EJBs will be used inside a Servlet.

For both Producer and Consumer, we need to declare a JMSContext annotated by @Inject and @JMSConnectionFactory. And declare a Queue annotated with @Resource.

The @Inject annotation tells the container to inject the JMSContext when it is needed. The @JMSConnectionFactory annotation tells the container the JNDI of the ConnectionFactory that it should use.

@Resource annotation on the Queue marks it as needed by the application. The container will inject an instance of the requested resource into the application component when the component is initialized by defining the jndi name of the resource.

to get the resource name from your glassfish server please in the admin console type this

asadmin_list_ressource

 

 

 

You can also create ConnectionFactory and Queue by typing this

asadmin_add_ressource

 

 

 

 

to see JMS Resources or create new ones inside the graphical console refer to screen below

glassfish_web_console_view_resource

 

Producer

Producer will act as a message sender


package srvEjb;

import javax.annotation.Resource;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.jms.JMSConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.Queue;

import com.srv.RemoteMessageProducer;

/**
 * Stateless Enterprise Java Bean acting as a Message Producer
 *
 * @author Younss AZZAYANI
 *
 */
@Stateless
@Remote(RemoteMessageProducer.class)
public class MessageProducer implements RemoteMessageProducer {
	/**
	 * JMS Context, This combines in a single object the functionality of two
	 * separate objects from the JMS 1.1 API: a Connection and a Session.
	 *
	 */
	@Inject
	@JMSConnectionFactory("jms/TestConnectionFactory")
	JMSContext context;

	/**
	 * Queue
	 */
	@Resource(mappedName = "jms/TestQueue")
	Queue queue;

	/**
	 * Send Message.
	 */
	@Override
	public void sendMessage(String message) {
		/*
		 * createProducer: Creates a new JMSProducer object which can be used to
		 * configure and send messages
		 */
		/*
		 * send: Send a TextMessage with the specified body to the specified
		 * destination, using any send options, message properties and message
		 * headers that have been defined on this JMSProducer.
		 */
		context.createProducer().send(queue, message);
	}
}

inside the sendMessage method we create  JMSProducer  and send the message param to the queue

Consumer
package srvEjb;

import javax.annotation.Resource;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.jms.JMSConnectionFactory;
import javax.jms.JMSContext;
import javax.jms.Queue;

import com.srv.RemoteMessageConsumer;

/**
 * Stateless Enterprise Java Bean acting as a Message Consumer.
 *
 * @author Younss AZZAYANI
 *
 */
@Stateless
@Remote(RemoteMessageConsumer.class)
public class MessageConsumer implements RemoteMessageConsumer {
	/**
	 * JMS Context, This combines in a single object the functionality of two
	 * separate objects from the JMS 1.1 API: a Connection and a Session.
	 *
	 */
	@Inject
	@JMSConnectionFactory("jms/TestConnectionFactory")
	private JMSContext context;
	/**
	 * Queue
	 */
	@Resource(mappedName = "jms/TestQueue")
	Queue queue;

	/**
	 * Receive Message.
	 */
	public String receiveMessage() {
		/*
		 * createConsumer: Creates a JMSConsumer for the specified destination
		 * (queue). A client uses a JMSConsumer object to receive messages that
		 * have been sent to a destination.
		 */
		/*
		 * receiveBody: Receives the next message produced for this JMSConsumer
		 * (context.createConsumer(queue)) and returns its body as an object of
		 * the specified type
		 */
		String message = context.createConsumer(queue)
				.receiveBody(String.class);
		return message;
	}
}

The Servlet (Optionnal):

You can also test your JMS Code by using jUnit or creating a simple App Class with main method.

package com.serv.servlet;

import java.io.IOException;
import java.io.Writer;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.srv.RemoteMessageConsumer;
import com.srv.RemoteMessageProducer;

/**
 * Servlet implementation class JMSServlet
 *
 * @author Younss AZZAYANI
 */

@WebServlet("/jms.html")
public class JMSServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private final static String SENDER_MESSAGE = "message";
	private final static String EMPTY_MESSAGE = "empty message";
	private final static String SPAN_TITLE_BEGIN = "<span style='font-weight:bold;font-style:italic;text-decoration:underline;color:red'>";
	private final static String SPAN_TITLE_END = "</span>";
	private final static String BR = "<br>";
	/**
	 * The producer
	 */
	@EJB
	RemoteMessageProducer producer;
	/**
	 * The Receiver
	 */
	@EJB
	RemoteMessageConsumer consumer;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		/* get */
		String message = request.getParameter(SENDER_MESSAGE);
		if (message == null || message.trim().length() == 0) {
			message = EMPTY_MESSAGE;
		}
		Writer writer = response.getWriter();

		writer.write(SPAN_TITLE_BEGIN + "Producer Message:" + SPAN_TITLE_END
				+ BR);

		writer.write(message + showTime());
		/* sending message */
		producer.sendMessage(message);

		writer.write(BR + SPAN_TITLE_BEGIN + "Consumer message:"
				+ SPAN_TITLE_END + BR);
		/* receiving message */
		String receivedMessage = consumer.receiveMessage();
		writer.write(receivedMessage + showTime());
	}

	private String showTime() {
		return " <span style='font-style:italic;color:green;'>at "
				+ System.currentTimeMillis() + " (Tms)</span>";
	}

}

RemoteMessageProducer and RemoteMessageConsumer are both interfaces implemented respectively by MessageProducer and MessageConsumer

and this is what you have to see when you invoke the servlet

result

Advertisements
About

A java Developer interested in Big Data,NoSQL, Functionnal and Dynamic programming

Tagged with: , ,
Posted in Java_corner
2 comments on “Simple JMS 2.0 Example within JEE7
  1. nschejtman says:

    Where are you taking com.srv.RemoteMessageProducer and com.srv.RemoteMessageConsumer from?

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: