Integrating asynchronous JMS processing in Oracle ADF Applications

In this article we will see how JMS can be used in ADF enterprise applications. We’re going to use Point-to-point model where a sender posts messages to a particular queue and a receiver reads messages from the queue.

This article is split in four sections. First section briefly explains the architectural concept of JMS. Second section will illustrate how to create the JMS System resources administratively from the WebLogic console. In the third section the JMSClient Class is shown which is used by the ADF client to input a message and send it to the JMS queue. The fourth section shows how the Message-Drive-Bean listens to the JMS Queue and consumes the message asynchronously.

You can download the sample ADF application for this article here. In order to run the sample app successfully it is required to complete second section

I. High-level JMS architecture overview

JMS allows the communication between different components of an application to be loosely coupled, reliable, and asynchronous.

The JMS API supports two models: Point-to-point (Queues) and Publish-and-subscribe (Topics).

Before starting to implement  I recommend you first understand the concepts of JMS which can be found here.

Figure 1. The JMS API Programming Model

The mechanisms for achieving message delivery are as follows:

  1. A client uses the Connection Factory object to create a Connection with the provider.
  2. The Connection object creates a Session object.
  3. Then the Session object creates the Message and the Message Producer objects.
  4. The Message Producer sends the message to the Destination i.e. a Queue.


II. Creating and maintaining objects administratively from WebLogic Console

JMS System resources such as destinations and connection factories are best maintained administratively rather than programmatically from the WebLogic console.  Such resources are configured and stored as JMS Modules.

The JMS Server is a container for the targeted destinations. It hosts the JMS modules and associated persistent stores that reside on a WebLogic Server instance.  A WebLogic instance can host one or more JMS Server.

WebLogic supports two types of persistent stores for saving JMS messages: JDBC-accessible  and disk-based file.

1. Creating the Persistent Store

Login to WebLogic console then navigate under Services, then select Persistent Stores. Click New and select Create FileStore and then proceed with the wizard to complete the required fields.

2. Creating the JMS Server

Navigate under Services – > Messaging -> Select JMS Servers .

Click New to create a new JMS Server. Select the Persistent store. Specify unique name for the JMS Server then click next and select the targeted WebLogic instance from the dropdown.

3. Creating JMS Modules

Navigate under Services – > Messaging -> Select JMS Modules . Click New to create a new JMS Module. Specify a name for the JMS Module then click next and select the targeted WebLogic instance.

4. Creating Subdeployment

Navigate under Services -> Messaging – > JMS Modules -> Select the Subdeployments tab. Click New button and then specify the Subdeployment Name and next select the targets for subdeployment, i.e. the Weblogic server instance and the JMS Server.

5. Creating the Connection Factory

Navigate under Services -> Messaging – > JMS Modules -> Select the JMS Module that you created above at step 3. Click New button and select Connection Factory. Next specify the Name of the Connection Factory and the JNDI Name which will be used for lookup by the client.

6. Creating the Queue

Navigate under Services -> Messaging – > JMS Modules -> Select the JMS Module that you created above at step 3. Click New button and select Queue. Next specify the Name of the Queue and the JNDI Name which will be used for lookup by the client. Next select the subdeployment you want to use ( i.e. one created on step 4 above).

III. Sending a message from  ADF Client to JMS Queue

The client demonstrates the tasks that a JMS application must perform:

  •     Creating a connection and a session
  •     Creating message producers
  •     Sending messages into the destination queue

The following class shows the above tasks:

package model;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.JMSSecurityException;
import javax.jms.MessageFormatException;
import javax.jms.MessageNotWriteableException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JMSClient
{

  public String putShortMessage(String queueJNDI, String connFactoryJNDI, String msgText) throws Exception {

    ConnectionFactory connectionFactory = null;
    javax.jms.Connection connection = null;
    javax.jms.Session session = null;
    Queue queue = null;
    Context ctx = new InitialContext();

    try{

      connectionFactory = (ConnectionFactory)ctx.lookup(connFactoryJNDI); //Connection Factory jndi api lookup
      queue = (Queue)ctx.lookup(queueJNDI); //Queue jndi api lookup

      connection = connectionFactory.createConnection(); //Connection Factory creates the Connection

      session = connection.createSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE); //Connection creates the Session

      MessageProducer messageProducer = session.createProducer(queue); //Session creates the Message Producer
      TextMessage message = session.createTextMessage(); //Session creates the Message
      message.setText(msgText);
      messageProducer.send(message); //Message Producer sends the message to Destination Queue

    } catch (NamingException e) {
      throw new RuntimeException(e);
    }
    catch(JMSSecurityException e){
      throw new RuntimeException(e);
    }
    catch(MessageNotWriteableException e){
      throw new RuntimeException(e);
    }
    catch(MessageFormatException e){
      throw new RuntimeException(e);
    }
    catch(JMSException e){
      throw new RuntimeException(e);
    }
    finally {
      connection.close();
    }

    return "Message sent successfully.";
  }
}


IV. Processing JMS messages asynchronously with the Message Drive Bean (MDB)

To receive JMS Queue messages asynchronously, we use a message-driven bean which acts as a JMS message listener.

To implement the MDB follow these steps as illustrated:


Once the wizard is complete the Message-Driven Bean with its annotation and onMessage() method are automatically generated. The onMessage() method needs to be updated accordingly to process the received message.

Below code shows the updated onMessage method.

package model;

import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(mappedName = "JmsQueue_1")

public class MessageDrivenEJBBean implements MessageListener {

/**
* Defines the actions when the message arrives
* This method should handle all exceptions. It must not throw checked exceptions,
* and throwing a RuntimeException, though possible, is considered a programming error.
* @param inMessage
*/

public void onMessage(Message inMessage)
{

   TextMessage txtmsg = null;

   try
   {

      //inMessage.acknowledge(); not required since the client creates the session in Session.AUTO_ACKNOWLEDGE mode.

      if (inMessage instanceof TextMessage)
      {

         txtmsg = (TextMessage)inMessage;

         String queueMessage = txtmsg.getText(); //get the queue message content

         System.out.println(queueMessage);

      }

   }

   catch (JMSException e)
   {
      System.err.println("Error MessageBean.onMessage 1 : " +"JMSException: " +      e.toString());
   }

   catch (Exception te)
   {
      System.err.println("Error MessageBean.onMessage 1 : " +"JMSException: " +      te.toString());
   }
}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值