Messaging makes its move,
Part 2 - JavaWorld - March 1999
Tutorial Details:
Messaging makes its move, Part 2
Messaging makes its move, Part 2
By: By Todd Sundsted
Put the finishing touches on your own Java-based messaging service by adding the required JMS veneer
s we learned last month , the Java Message Service Specification (JMS spec) defines an interface for message services but does not define an implementation. Unlike the JDK, if you download the JMS source code from Sun's Web site (see Resources ) and examine it, you'll find only interfaces; there are no classes at all (well, actually there are two -- but they are helper classes and not really part of the specification). After a moment's reflection it should be clear why this would be true.
There exists a large body of legacy enterprise applications built around existing messaging products. Given this fact, the JMS architects decided it was more important to allow enterprise Java developers to develop applications that worked within the context of an existing messaging infrastructure than to try to get them to adopt an entirely new product. Of course, developers should be able to create applications without creating additional dependencies on any particular vendor -- thus the JMS spec would be vendor neutral but compatible with existing products.
I've decided to create an implementation of the JMS API in Java for two reasons:
For those inclined to technical challenges, creating a Java-based implementation provides an excellent introduction to the practice of writing message-oriented middleware.
For those interested in learning to use the JMS API, creating a Java-based implementation provides a reference to play with. Without it, you'd have to purchase an existing messaging product and the Java interface as well.
I'll begin by presenting the JMS API as it would appear to someone creating an implementation -- that is, as it would appear from the inside.
But I need to share with you one caveat before I begin.
While the JMS API isn't the most complicated of the Java Enterprise APIs, it isn't the least complicated, either. Due to time and space constraints, I haven't made a heroic effort to implement the entire JMS API Specification. I have, however, taken the time to implement a workable subset. Just to be on the safe side, I'll let you know where my implementation comes up short.
You might find it useful to begin with a refresher. Last month I built the classes that implemented the basic underlying functionality of a message service and I presented the basic philosophy behind the JMS API. If you already feel comfortable with that material, then please continue.
A tale of two domains
Recall that the elements of the JMS API are divided into two domains, each representing one of the two leading models of messaging provided by existing messaging products. The two models are the point-to-point model and the publish/subscribe model.
While the behavior of the classes within each domain differ, their APIs are nearly identical. It's the APIs and their use that we're interested in this month.
If you glance at the relationship between the point-to-point and publish/subscribe interfaces, you'll see what I mean.
Point-to-point
Publish/subscribe
Parent interface
Queue
Topic
Destination
QueueConnectionFactory
TopicConnectionFactory
ConnectionFactory
QueueConnection
TopicConnection
Connection
QueueSession
TopicSession
Session
QueueSender
TopicPublisher
MessageProducer
QueueReceiver
TopicSubscriber
MessageConsumer
The first column lists the principle interfaces that define the point-to-point half of the API. The second column lists the principle interfaces that define the publish/subscribe half of the API. The third column lists the parent interfaces from which both the point-to-point and the publish/subscribe interfaces inherit. Note how similar the two domains are from the standpoint of these interfaces.
Since the two APIs are nearly identical, you can get a good feel for the use of both interfaces by looking at either.
Destinations
The Destination , Queue , and Topic interfaces represent administered objects . Administered objects are created by an administrator and are registered with a directory. They represent globally accessible resources. In this case, they are used to encapsulate the identity (or address) of a message destination such as a queue or a topic. They are not themselves a destination. They provide a platform-independent way to encapsulate provider-specific addresses. Destination objects support concurrent use.
The following code demonstrates how the Queue interface and associated implementation class Queue_Impl are implemented. The code for the Topic interface is nearly identical.
First the Queue interface:
public
interface Queue
extends Remote
{
public
String
getQueueName()
throws RemoteException;
}
Then the Queue_Impl interface:
public
class Queue_Impl
extends UnicastRemoteObject
implements Queue
{
private String _stringQueueName = null;
public
Queue_Impl(String stringQueueName)
throws RemoteException
{
_stringQueueName = stringQueueName;
}
public
String
getQueueName()
throws RemoteException
{
return _stringQueueName;
}
public
int
hashCode()
{
return _stringQueueName.hashCode();
}
public
boolean
equals(Object object)
{
return object.equals(_stringQueueName);
}
}
Connection factories
The ConnectionFactory , QueueConnectionFactory , and TopicConnectionFactory interfaces represent administered objects . They encapsulate a set of configuration parameters that have been defined by an administrator. A client uses a ConnectionFactory to create a Connection with a JMS provider. They simplify the administration of a message service in a large-scale enterprise setting. ConnectionFactory objects support concurrent use.
Since our implementation has no interesting administrative infrastructure, the only method implemented is the method that returns a connection. The following interface and implementation classes illustrate how this looks within the queue domain. Once again, the topic source code is nearly identical.
First the QueueConnectionFactory interface:
public
interface QueueConnectionFactory
extends Remote
{
public
QueueConnection
createQueueConnection()
throws RemoteException;
}
Then the QueueConnectionFactory_Impl interface:
public
class QueueConnectionFactory_Impl
extends UnicastRemoteObject
implements QueueConnectionFactory
{
public
QueueConnectionFactory_Impl()
throws RemoteException
{
}
public
QueueConnection
createQueueConnection()
throws RemoteException
{
return new QueueConnection();
}
}
Connections
The Connection , QueueConnection , and TopicConnection interfaces represent an active connection to a JMS provider. They are the conduit through which communication flows. A client uses them to create a Session with the JMS provider. They provide a single point for all communication activities -- thus enabling resource (such as connection) pooling as well as authentication and security. Connection objects support concurrent use.
The following code illustrates the implementation within the queue domain.
public
class QueueConnection
implements Serializable
{
private Hashtable _hashtable = new Hashtable();
private
HQueue
lookup(Queue queue)
throws MalformedURLException,
NotBoundException,
UnknownHostException,
RemoteException,
IOException
{
HQueue hqueue = null;
if ((hqueue = (HQueue)_hashtable.get(queue)) != null)
{
return hqueue;
}
hqueue = (HQueue)Naming.lookup(queue.getQueueName());
_hashtable.put(queue, hqueue);
return hqueue;
}
void
send(Message message, Queue queue)
throws NotBoundException,
RemoteException,
IOException
{
lookup(queue).send(message);
}
Message
receive(Queue queue)
throws NotBoundException,
RemoteException,
IOException
{
return lookup(queue).receive();
}
public
QueueSession
createQueueSession()
{
return new QueueSession(this);
}
}
Sessions
The Session , QueueSession , and TopicSession interfaces represent a single threaded context for sending and receiving messages. A client uses them to create one or more MessageProducers or MessageConsumers . They also provide a factory for creating messages and define a serial order for the messages they consume or produce. Sessions provide a natural way for clients to organize interactions with a provider.
The following code illustrates an implementation.
public
class QueueSession
implements Serializable
{
private QueueConnection _queueconnection = null;
QueueSession(QueueConnection queueconnection)
{
_queueconnection = queueconnection;
}
void
send(Message message, Queue queue)
throws NotBoundException,
RemoteException,
IOException
{
_queueconnection.send(message, queue);
}
Message
receive(Queue queue)
throws NotBoundException,
RemoteException,
IOException
{
return _queueconnection.receive(queue);
}
public
QueueSender
createSender(Queue queue)
{
return new QueueSender(this, queue);
}
public
QueueReceiver
createReceiver(Queue queue)
{
return new QueueReceiver(this, queue);
}
}
Message producers
The MessageProducer , QueueSender , and TopicPublisher interfaces represent objects that are used to send messages to a destination.
public
class QueueSender
implements Serializable
{
private QueueSession _queuesession = null;
private Queue _queue = null;
QueueSender(QueueSession queuesession, Queue queue)
{
_queuesession = queuesession;
_queue = queue;
}
public
void
send(Message message)
throws NotBoundException,
RemoteException,
IOException
{
_queuesession.send(message, _queue);
}
}
Message consumers
The MessageConsumer , QueueReceiver , and TopicSubscriber interfaces represent objects that are used to receive messages sent to a destination.
public
class QueueReceiver
implements Serializable
{
private QueueSession _queuesession = null;
private Queue _queue = null;
QueueReceiver(QueueSession queuesession, Queue queue)
{
_queuesession = queuese
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Messaging makes its move,
Part 2 - JavaWorld - March 1999
View Tutorial: Messaging makes its move,
Part 2 - JavaWorld - March 1999
Related
Tutorials:
Enhance your Java application with Java Native Interface (JNI)
Enhance your Java application with Java Native Interface (JNI) |
XML messaging, Part
3
XML messaging, Part
3 |
Connect the
enterprise with the JCA, Part 1
Connect the
enterprise with the JCA, Part 1 |
Implement a J2EE-aware application console in Swing
Implement a J2EE-aware application console in Swing |
Rumble in the
jungle: J2EE versus .Net, Part
1
Rumble in the
jungle: J2EE versus .Net, Part
1 |
Jabber away with instant
messaging
Jabber away with instant
messaging |
Jini's relevance emerges, Part
1
Jini's relevance emerges, Part
1 |
Jini's relevance emerges, Part
2
Jini's relevance emerges, Part
2 |
J2SE 1.4
breathes new life into the CORBA community, Part
1
J2SE 1.4
breathes new life into the CORBA community, Part
1 |
Yes, you can secure your Web services documents, Part 2
Yes, you can secure your Web services documents, Part 2 |
Should you go
with JMS?
Should you go
with JMS? |
SAAJ: No strings attached
SAAJ: No strings attached |
Good, but
obsolete
Good, but
obsolete |
Interesting
concept ...
Interesting
concept ... |
An Intelligent Nim Computer Game, Part 1
An Intelligent Nim Computer Game, Part 1
In this article, you learn how to play Nim, and discover tools for creating an intelligent computer player. In the next article, you apply those tools to the creation of that player, while building console and G |
JSP (JavaServer Pages) is a standard for combining Java and HTML to provide dynamic content in web pages.
With JSP, you embed Java code in HTML using special JSP tags similar to HTML tags. You install the JSP page, which has a .jsp extension, into the WebLogic Server document root, just as you would a static HTML page. When WebLogic Server serves a JSP page.. |
Power Messaging, Maps and more...
BuddySpace is an instant messenger with four novel twists: (1) it allows optional maps for geographical & office-plan visualizations in addition to standard 'buddy lists'; (2) it is built on open source Jabber, which makes it interoperable with ICQ, MSN, |
Getting Started with Java Message Service (JMS)
The Java Message Service (JMS) is designed to allow Java applications to use enterprise messaging systems. It makes it easy to develop enterprise applications that asynchronously send and receive business data and events. Learn how to implement it for you |
J2ME Technology Turns 5!
In 2004 the Java 2 Platform, Micro Edition (J2ME) celebrated its fifth anniversary. This article presents where J2ME is today. |
Five Reasons to Move to the J2SE 5 Platform
Five important reasons to move to the Java 2 Platform, Standard Edition (J2SE platform) 5.0, supported by data and references to prove that the 5.0 release will reduce development and runtime costs. |
|
|
|