免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1189 | 回复: 0
打印 上一主题 下一主题

Master JMS Messaging with OpenJMS [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-10-20 18:28 |只看该作者 |倒序浏览


rganizations are increasingly demanding applications where communication between software components is loosely coupled and often asynchronous. In asynchronous communication, an application sends a message, and then continues program execution without waiting for a response. In a loosely coupled system, the sending program might not even know where or what the recipient is, because the communication between software components takes place via messaging. The Java Messaging Service (JMS) is the only messaging API supported by J2EE.


OpenJMS, a SourceForge project, is a free open source implementation of Sun Microsystems' JMS API 1.0.2 specification. In this article you'll see how to install and use OpenJMS, along with code samples that illustrate the point-to-point and publish/subscribe messaging models it supports.
This article is not intended to be a tutorial on JMS; rather, it's intended to show you how to use OpenJMS. If you are unfamiliar with JMS basics you should consider taking a look at Sun's
Java Message Service Tutorial
before reading this article.
Obtaining and Installing OpenJMS
You can download OpenJMS from
http://openjms.sourceforge.net/downloads.html
. OpenJMS runs in both Windows and UNIX environments, and requires a Java 2 runtime environment. Throughout this article, I'll assume you're using Windows as your operating platform. Refer to the
OpenJMS documentation
for UNIX instructions. At the time of this article's writing, OpenJMS was in version 0.7.6. The download contains the code necessary for running the OpenJMS server as well as the client JARS needed to write client applications that interact with the server. The download also includes documentation and sample programs.
To install OpenJMS, simply extract the files from the downloaded archive with WinZip, or with the JAR tool using the command:
   jar xvf openjms-0.7.6.zip
Before firing up the OpenJMS server, you need to set a couple of environment variables: a JAVA_HOME variable pointing to the directory where your Java 2 runtime is installed (e.g., C:jdk1.3.1_11in) and an OPENJMS_HOME variable pointing to the OpenJMS install directory (e.g., C:openjms-0.7.6).
To start the OpenJMS messaging server, use the following commands:
   cd %OPENJMS_HOME%in
   startup
Similarly, you can shut down the server using the shutdown command.
   cd %OPENJMS_HOME%in
   shutdown
After launching the server, you are ready to interact with it using Java programs that leverage the JMS API. Client applications must have the appropriate jar files: jms-1.02a.jar, openjms-0.7.6.jar, and openjms-client-0.7.6.jar on the Java build path. You'll find all these in the lib directory of your OpenJMS installation.
Getting a JNDI Context
By default, OpenJMS uses an embedded JNDI (Java Naming and Directory Interface) provider which listens to port 1099. As you will see, you can use JNDI to store connection factories, topics, and queues. OpenJMS allows you to use a third-party JNDI provider, but this article's code uses the embedded provider. To access topics and queues, you will need to create a JNDI context exemplified with the code below:
   import java.util.Hashtable;
   import javax.naming.Context;
   import javax.naming.InitialContext;
   ...
   Hashtable properties = new Hashtable();
   properties.put(Context.INITIAL_CONTEXT_FACTORY,
      "org.exolab.jms.jndi.InitialContextFactory");
   properties.put(Context.PROVIDER_URL,
      "rmi://localhost:1099/");
   Context context = new InitialContext(properties);
You'll see the syntax above in all the provided code samples, so for brevity, in the remainder of this article you'll see a comment where the boilerplate code belongs.



Download The Code for this Article
Point-to-point Messaging with OpenJMS
You should recall that in the point-to-point messaging style, a sender sends messages to a queue. In this messaging model, messages are received by one—and only one—receiver.Writing to a Queue
Writing to a queue consists of the following steps:
  • Obtain the JNDI context.
  • Contact the JMS provider, OpenJMS, and get a JMS connection from the queue connection factory.
  • Create a queue connection using the connection factory.
  • Establish a queue session for the newly established connection.
  • Lookup the target queue destination.
  • Create a queue sender that will be used to send messages and associate it to the queue session.
  • Send a message using the queue sender. The code for the QueueSend class shown below follows these steps. Note that it uses a queue named queue1 The OpenJMS install pre-configures this queue by default; however you can refer to the section
    Creating Your Own Topics and Queues
    in this article to see how to configure your own queues.
       public class QueueSend
       {
          public static void main(String[] args)
          {
             try
             {
                // standard boilerplate code to establish a
                 // JNDI context and connection
                
                // retrieve queue connection factory
                QueueConnectionFactory
                   queueConnectionFactory =
                   (QueueConnectionFactory)context.lookup(
                   "JmsQueueConnectionFactory");
       
                // create a queue connection
                QueueConnection queueConnection =         
                  queueConnectionFactory.
                  createQueueConnection();
                
                // create a queue session
                // set transactions to false and set auto
                // acknowledgement of receipt of messages
                QueueSession queueSession =
                   queueConnection.createQueueSession(
                   false,Session.AUTO_ACKNOWLEDGE);
                
                // retrieve queue
                Queue queue =
                   (Queue)context.lookup("queue1");
                
                // create a queue sender and associate to
                // the retrieved queue
                QueueSender queueSender =
                   queueSession.createSender(queue);
                
                // send a message to the queue
                TextMessage message =
                   queueSession.createTextMessage();
                message.setText("Hello there.");
                queueSender.send(message);
                
                System.out.println(
                   "Sample application writing message to " +
                      "queue.");
                
                // clean up
                   ...
                         
             }
             catch (NamingException e)
             {
                e.printStackTrace();
             }
             catch (JMSException e)
             {
                e.printStackTrace();
             }
          }
       }
    Now that you've seen how to write a message to the queue, you can retrieve the message from the queue either synchronously or asynchronously.
    Synchronous and Asynchronous Retrieval
    Retrieving a message synchronously is similar to the process of writing to the queue, but instead of using a QueueSender object, you use a QueueReceiver object. You must also call the start() method on the queue connection, which starts the delivery of incoming messages. After doing that, you receive messages by calling the synchronous receive() method, as shown in the QueueReceiveSynchronous class below.
       public class QueueReceiveSynchronous
       {
          public static void main(String[] args)
          {
             try
             {
                // standard boilerplate code to establish a JNDI
                 //  context and connection
                
                // retrieve queue connection factory
                QueueConnectionFactory
                   queueConnectionFactory =
                   (QueueConnectionFactory)context.lookup(
                   "JmsQueueConnectionFactory");
                
                // create a queue connection
                QueueConnection queueConnection =
              queueConnectionFactory.createQueueConnection();
                
                // start delivery of incoming messages
                queueConnection.start();
                
                // create a queue session
                // set transactions to false and set auto
                // acknowledgement of receipt of messages
                QueueSession queueSession =
                   queueConnection.createQueueSession(
                   false,Session.AUTO_ACKNOWLEDGE);
                
                // retrieve queue
                Queue queue =
                   (Queue)context.lookup("queue1");
                
                // create a queue receiver and associate
                // to the retrieved queue
                QueueReceiver queueReceiver =
                   queueSession.createReceiver(queue);
                
                // receive message using the synchronous
                // receive method
                Message message = queueReceiver.receive();
                String messageText = null;
                if (message instanceof TextMessage)
                   messageText =
                      ((TextMessage)message).getText();
                System.out.println(messageText);
                
                // clean up
                 ...
             }
             catch (NamingException e)
             {
                e.printStackTrace();
             }
             catch (JMSException e)
             {
                e.printStackTrace();
             }
          }
       }
    Asynchronous Retrieval
    To listen asynchronously to the queue, register an object that implements the MessageListener interface, that simply requires you to implement the onMessage method, in which you process the incoming message as desired. The QueueReceiveAschynchronous class shown in
    [url=javascript:showSupportItem('listing1');]Listing 1[/url]
    receives messages asynchronously.
    Publish/Subscribe Messaging with OpenJMS
    The other major message domain supported by JMS is called publish/subscribe. In the publish-and-subscribe messaging style, a publisher sends messages to a topic, and those messages may be received by one or more subscribers.
    Writing to a topic is not much different from writing to a queue. Take a look at the code below, which places a message on a topic. In essence, you have just replaced references to a queue with a topic. This time, the code leverages a TopicConnectionFactory as opposed to a QueueConnectionFactory. Similarly, it uses a TopicConnection, a TopicSession, and a TopicPublisher (as opposed to a QueueConnection, QueueSesion, and QueueSender respectively).
    Writing to a topic is often referred to as "publishing," and reading from a topic is called "subscribing." In the point-to-point messaging domain vernacular, writing to a queue is called sending and reading from a queue is called receiving. Take note that just as you wrote to queue1 in the point-to-point example, you'll now write to topic1 (again, a topic which the OpenJMS install process preconfigures. Refer to the section
    Creating Your Own Topics and Queues
    to find out how to create a different topic.
    Unlike in the point-to-point to messaging domain however, messages in the publish/subscribe domain are not persistent. Thus, when you run a typical publisher, a subscriber program (presented in the next section) must be running to receive the messages. You can remove the requirement that the subscriber must be running by using durable subscriptions, which I'll cover in a future article.
       public class TopicPublish
       {
          public static void main(String[] args)
          {
             // standard boilerplate code to
              // establish a JNDI context and connection
             try
             {
                // retrieve topic connection factory
                TopicConnectionFactory factory =
                  (TopicConnectionFactory)context.lookup(
                  "JmsTopicConnectionFactory");
                
                // create a topic connection using factory
                TopicConnection topicConnection =
                   factory.createTopicConnection();
                topicConnection.start();
                
                // create a topic session
                // set transactions to false and set auto
                // acknowledgement of receipt of messages
                TopicSession topicSession =
                   topicConnection.createTopicSession(
                   false,Session.AUTO_ACKNOWLEDGE);
                
                // lookup the topic, topic1
                Topic topic = (Topic)
                   context.lookup("topic1");
                
                // create a topic publisher and associate
                // to the retrieved topic
                TopicPublisher topicPublisher =
                   topicSession.createPublisher(topic);
                
                // publish a message to the topic
                System.out.println(
                   "Sample application publishing " +
                   "a message to a topic.");
                TextMessage message =
                   topicSession.createTextMessage(
                      "Hello world");
                topicPublisher.publish(message);
                
                // clean up
                ...
             }
             catch (NamingException e)
             {
                e.printStackTrace();
             }
             catch (JMSException e)
             {
                e.printStackTrace();
             }
          }
       }Reading from a Topic (a.k.a. Subscribing)
    The code for retrieving messages from the topic is programmatically very similar to retrieving messages from a queue. You can retrieve messages both synchronously and asynchronously in the publish/subscribe message domain, just as you can in the point-to-point messaging domain. Listings
    [url=javascript:showSupportItem('listing3');]3[/url]
    and
    [url=javascript:showSupportItem('listing1');]4[/url]
    show examples of each. Paralleling the point-to-point examples, the class TopicSubscribeSynchronous.java (see
    [url=javascript:showSupportItem('listing2');]Listing 2[/url]
    ) uses the "receive" method.
    On the other hand, the TopicSubscribeAsynchronous.java class (see
    [url=javascript:showSupportItem('listing3');]Listing 3[/url]
    ) uses the onMessage method, which it is obligated to do because it implements the MessageListener interface.
    After running TopicPublish a number of times, you'll see that the TopicSubscribeAsynchronous application processes each incoming message on the topic1 topic (see
    [url=javascript:showSupportItem('figure1');]Figure 1[/url]
    ).
    [url=javascript:showSupportItem('figure2');][/url]

    [url=javascript:showSupportItem('figure2');]Figure 2[/url]
    : The OpenJMS Administrator GUI: You can use the Administrator GUI application to create and configure queues and topics, as well as configure JNDI, security, and garbage collection settings.Creating Your Own Topics and Queues
    The
    sample code
    for this article uses instances (queues and topics) preconfigured by the install program for OpenJMS. You can create your own queues and topics using the OpenJMS administration API, via the OpenJMS configuration file (openjms.xml) or via the OpenJMS Administrator GUI. You launch the Administrator GUI by running the admin batch file in the bin directory (see
    [url=javascript:showSupportItem('figure2');]Figure 2[/url]
    ).
    You can configure a number of items (JNDI, Security, Garbage Collection) via XML configuration files (see the
    OpenJMS configuration documentation on SourceForge
    ).
    To add queues and topics, simply add to the  section of the openjms.xml file (located in the config directory of your OpenJMS installation):
       
          
             
             
          
          
         
          
          
          
         
    For example, to add a topic named "kulvirTopic" and a queue named "kulvirQueue" you would modify the configuration file as follows:
       
          
             
             
          
          
             
       
          
          
          
          
         
    After modifying the configuration file, restart OpenJMS. The new configuration binds both the new kulvirTopic topic and the new kulvirQueue queue in JNDI.
    OpenJMS Limitations
    OpenJMS does have some limitations. For example, OpenJMS does not support XA transactions or high availability through clustering and failover. Consequently, if you need those more advanced and coveted features, a commercial JMS implementation might be more appropriate. Despite its enterprise-level limitations, OpenJMS is a great tool for learning JMS programming.
    In this article, you saw how to interact with the JMS server programmatically using small client applications and how to create new queues and topics for the OpenJMS server by modifying its configuration file. I have covered only the basics of OpenJMS; there is a lot more to it than appears in this article. You can learn more about OpenJMS on the
    project homepage
    . The open source community improves OpenJMS constantly, so check for updates often.
    Writing to a Topic (a.k.a. Publishing)

    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/8502/showart_52741.html
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP