Access AQ JMS Destinations From OC4J Web Application

Overview

* Setup Oracle AQ in Oracle database.
* Setup data source in data-sources.xml file.
* Setup resource provider in orion-application.xml.
* Setup logical JNDI names for JMS connection factories and destinations in web.xml file.
– Use <resource-ref> for connection factories.
– Use <resource-env-ref> for destinations.
* Map logical JNDI names to actual JNDI names in orion-web.xml file.
* Package into EAR file and deploy to OC4J.

Setup Oracle AQ

* See this post for details.

Setup data source

* Add to EAR data-sources.xml

<managed-data-source 
  login-timeout='-1'
  connection-pool-name='MyAQUserDSPool'
  jndi-name='jdbc/xa/MyAQUserDS'
  name='MyAQUserDS'
  tx-level='global'
  manage-local-transactions='false'/>
 
<connection-pool name='MyAQUserDSPool'>
  <connection-factory 
    factory-class='oracle.jdbc.pool.OracleDataSource'
    user='MyAQUser'
    password='MyAQUserPass'
    url='jdbc:oracle:thin:@localhost:1521:orcl'>
    <proxy-interface sql-object='Connection' 
      interface='oracle.jdbc.internal.OracleConnection'/>
    <proxy-interface sql-object='Statement' 
      interface='oracle.jdbc.OracleStatement'/>
    <proxy-interface sql-object='CallableStatement' 
      interface='oracle.jdbc.OracleCallableStatement'/>
    <proxy-interface sql-object='PreparedStatement' 
      interface='oracle.jdbc.OraclePreparedStatement'/>
    <proxy-interface sql-object='ResultSet' 
      interface='oracle.jdbc.OracleResultSet'/>
  </connection-factory>
</connection-pool>

Setup Resource Provider

* Add to EAR orion-application.xml

<data-sources path="./data-sources.xml"/>
<resource-provider 
  class="oracle.jms.OjmsContext" 
  name="MyAQJMSResourceProvider">
  <property name="datasource" 
    value="jdbc/xa/MyAQUserDS"/>
</resource-provider>

Setup Logical JNDI Names

* Add to WAR web.xml. Make sure to use resource-ref for connection factories and resource-env-ref for destinations.

<resource-ref>
  <res-ref-name>jms/TopicConnectionFactory</res-ref-name>
  <res-type>javax.jms.TopicConnectionFactory</res-type>
  <res-auth>Container</res-auth>
</resource-ref>
<resource-env-ref>
  <resource-env-ref-name>jms/sensorConfigTopic</resource-env-ref-name>
  <resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
</resource-env-ref>

Map Logical JNDI Names

* Add to orion-web.xml. Make sure to use resource-ref-mapping for connection factories and resource-env-ref-mapping for destinations.

<resource-ref-mapping
  name="jms/TopicConnectionFactory"
  location="java:comp/resource/MyAQJMSResourceProvider/TopicConnectionFactories/MyTCF"/>
 
<resource-env-ref-mapping
  name="jms/sensorConfigTopic"
  location="java:comp/resource/MyAQJMSResourceProvider/Topics/MyAQUser.TEST_TOPIC"/>

Package into EAR File and Deploy to OC4J Container

Sample Code

* Sample code to receive message from an AQ topic.

import javax.jms.JMSException;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
import org.apache.log4j.Logger;
 
public class JMSUtil {
  static Logger log = Logger.getLogger(JMSUtil.class.getName());
  private static final String TOPIC_CONN_FACTORY =
      "java:comp/env/jms/TopicConnectionFactory";
  private static final String TEST_TOPIC =
      "java:comp/env/jms/TestTopic";
 
  public static void main(String[] args) {
      JMSUtil util = new JMSUtil();
 
      TextMessage tm;
      try {
          tm = util.receiveTest("testId");
      } catch (JMSException e) {
          log.error(e);
      } catch (NamingException e) {
          log.error(e);
      }
  }
 
  public TextMessage receiveTest(String subscriberID)
      throws NamingException, JMSException {
      log.debug("============================");
      log.debug("Start receiveTest...");
      log.debug("============================");
      Context ctx = null;
      TopicConnectionFactory tcf = null;
      TopicConnection conn = null;
      Topic topic = null;
      TextMessage msg = null;
      TopicSession session = null;
      TopicSubscriber sub = null;
      try {
          ctx = new InitialContext();
          log.debug("got InitialContext.");
 
          tcf = 
              (TopicConnectionFactory)ctx.lookup(TOPIC_CONN_FACTORY);
          log.debug("got TopicConnectionFactory.");
          conn = tcf.createTopicConnection();
          log.debug("got conn.");
          topic = (Topic)ctx.lookup(TEST_TOPIC);
          log.debug("got topic.");
          session = conn.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
          conn.start();
          log.debug("strated conn.");
          sub = session.createDurableSubscriber(topic, subscriberID);
          msg = (TextMessage)sub.receive(5000);
          if (msg != null){
              log.debug(msg.getText());
          } else {
              log.debug("No message");
          }
      } finally {
          if (sub != null)
              sub.close();
          if (session != null)
              session.close();
          if (conn != null)
              conn.close();
      }
      log.debug("done.");
      return msg;
  }
 
}
This entry was posted in oc4j. Bookmark the permalink.