Skip Headers

Oracle® Containers for J2EE Services Guide 10g Release 3 (10.1.3) B14427-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 3 Oracle Enterprise Messaging Service (OEMS)

The Oracle Enterprise Messaging Service (OEMS) provides a robust messaging platform for building and integrating distributed applications. It provides the framework for Oracle's messaging and message integration solutions.

The following key features make up OEMS:

- Standardized interface

  - Java Message Service (JMS) and J2EE Connector Architecture (J2CA)

- Quality of Service choice for message persistence

  - In-Memory, File-Based, or Oracle Database

- Seamless Integration with non-Oracle messaging systems

  - JMS Connector, JMS Router, and Messaging Gateway (MGW)

All of these areas are covered in this chapter. The only OEMS feature not covered here is MGW, which is documented in the Oracle Streams Advanced Queuing User's Guide and Reference document.

Note: In past releases, Oracle has used the terms "OracleAS JMS" and "OJMS" when describing the In-Memory, File-Based, Database persistence options. "OracleAS JMS" referred to the In-Memory and File-Based options while "OJMS" referred to JMS interface to Streams Advanced Queuing (AQ). To avoid any confusion regarding JMS, the "OracleAS JMS" and "OJMS" nomenclature will not be used. The "OEMS JMS" reference will be used instead. This reflects the fact that Oracle offers a single JMS interface to the three message persistence options. Your JMS application code will not have to change if you decide to change message persistence between any of the three quality of service choices.

This chapter discusses the following topics:

- JMS Tasks

- New JMS Features

- About JMS

- JMS Configuration Overview

- OEMS JMS In-Memory and File-Based Persistence

- OEMS JMS Database Persistence

- JMS Connector

- Resource Providers

- Sending and Receiving JMS Messages

- Using High Availability and Clustering for OEMS JMS

- JMS Router

JMS Tasks

This chapter discusses the following JMS tasks:

- Configuring Destination Objects and Connection Factories.

- Configuring Ports

- Sending and Receiving JMS Messages

- Declaring the OEMS JMS Database Reference

- Enabling File-Based Persistence in the Application Server Control Console

- Using Logical Names to Reference Resources

- Using Third-Party JMS Providers

- Using Message-Driven Beans

- Using High Availability and Clustering for OEMS JMS

New JMS Features

The following OC4J JMS features and behaviors are new for this release:

- JMS 1.1 and J2EE 1.4 Compliance - OEMS JMS is JMS 1.1 compliant and J2EE 1.4 compliant.

  You can access the JMS 1.1 specification at: `http://java.sun.com/products/jms/docs.html`.

  You can access the J2EE 1.4 specification at: `http://java.sun.com/j2ee/1.4/docs/index.html`

- Domain Unification - You can use the same JMS connection and session to operate on OEMS JMS queues and topics. This is a JMS 1.1 feature.

- JMS Connector - The JMS Connector is a generic JMS J2CA resource adapter used to integrate the OEMS JMS In-Memory, File-Based, and Database resource providers, as well as non-Oracle JMS providers, in to OC4J. Supported non-Oracle JMS providers that can be integrated are WebSphereMQ, Tibco, and SonicMQ. All of these providers are now fully integrated with OC4J. The JMS Connector supports MDBs. Other significant advantages are:

  - Support for global transactions

  - MDBs that react to changing loads

  - JMS connection pooling (not implemented for applications running in a non-managed environment)

  - Performance enhancement features: Lazy enlistment of global transactions and lazy evaluation of JMS operations. Certain operations, such as enlisting resources and looking up connection factories and destinations are not performed until necessary.

  For discussion of the Resource Adapter, see Oracle Containers for J2EE Resource Adapter Administrator's Guide.

- Support for Message Driven Beans (MDB) for the following JMS resource providers:

  - OEMS JMS In-Memory, File-Based, and Database

  - IBM WebSphere MQ-based JMS

  - TIBCO Enterprise for JMS

  - SonicMQ

- Transactions across Domains - You can engage queues and topics in the same transaction. This is a JMS 1.1 feature.

- JMS Router - The JMS Router provides message-bridging routing services. The JMS Router is discussed in the "JMS Router" section starting.

- Oracle and Third-party Support - The following JMS message providers are officially supported through the JMS Connector bundled with OC4J:

  - OEMS JMS In-Memory, File-Based, and Database

  - IBM WebSphere MQ for JMS versions 6.0 and 5.3 resource provider

  - TIBCO Enterprise for JMS version 3.1.0

  - SonicMQ JMS 6.0

  For information on the third-party providers, see "Resource Providers" . The demos that demonstrate configuration and usage of the JMS providers through the Resource Adapter are available at `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`.

- Start-order independence - See the "JMS Connector" section section for details.

- Demo Code - Demos for various JMS configuration functions are available at `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`.

  For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

## 3.1 About JMS

Java clients and Java middle-tier services must be capable of using enterprise messaging systems. Java Message Service (JMS) offers a common way for Java programs to access these systems. JMS is the standard messaging API for passing data between application components and allowing business integration in heterogeneous and legacy environments.

Before reading this chapter, you should be familiar with the basics of JMS and the JMS API. For basic information about JMS, including tutorials and the API documentation, visit the Sun Microsystems Web site at:

`http://java.sun.com/products/jms/index.htm`

JMS provides two messaging domains, each associated with a JMS destination type, and a domain-specific set of Java interfaces:

- Point-to-Point—Messages are sent to a single consumer using a JMS queue.

- Publish/Subscribe—Messages are broadcast to all registered listeners using a JMS topic.

JMS destination objects are bound in the JNDI environment and made available to J2EE applications.

In addition to providing two sets of messaging interfaces, one for each messaging domain, JMS (starting with JMS 1.1) also provides a set of common interfaces for implementing domain-independent application code. This set of common interfaces maintains the distinct behavior of the two messaging domains (where the behavior is governed by the messaging domain used, as associated with the JMS destination type), while providing common programming interfaces for both messaging domains. The interfaces belonging to this set of common interfaces, as well as how they relate to the domain-specific interfaces, are detailed in Table 2-1 in the JMS 1.1 specification document.

Backward Compatibility

Oracle recommends that newer JMS applications be deployed using the JMS Connector, which is based on the J2CA 1.5 specification and mandated by the J2EE 1.4 standard. This path provides the new features introduced in OracleAS 10.1.3. However, Oracle will continue to support JMS applications deployed using the older proprietary OC4J Resource Provider supported in OracleAS 9.0.4/10.1.2.

The Oracle JMS Connector is discussed in the "JMS Connector" section starting.

### 3.1.1 JMS How-To Documents and Demo Sets

How-To documents and a set of examples, including commented configuration files, are available at the How-To website: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

The JMS documents and demo sets are listed under the Messaging (JMS) heading. The documents and deployment descriptor files in the demo set are organized by resource provider and include the configuration variations called for by the various supported resource providers. Unzip the files that apply to the relevant resource provider.

Table 3-1, "JMS How-To Documents and Demo Sets" lists the JMS topics, the associated How-To documents, and their demo set ZIP files.

Table 3-1 JMS How-To Documents and Demo Sets

JMS Topic | How-To Document URL | Demo Set ZIP File
--- | --- | ---
How To Use the JMS Router for OracleAS JMS and Oracle OJMS | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-use-JMS-router/doc/How-to-Use-JMS-Router.html` | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-use-JMS-router/how-to-use-JMS-router.zip`
How-To Configure and Use MQ Series® JMS with OC4J 10g (10.1.3) JCA 1.5 Resource Adapters | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-mq-jms/doc/how-to-mq-jms.html` | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-mq-jms/how-to-mq-jms.zip`
How to Configure and Use Oracle's Generic JMS Resource Adapter with OracleAS JMS | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-oracleasjms/doc/how-to-gjra-with-oracleasjms.html` | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-oracleasjms/how-to-gjra-with-oracleasjms.zip`
How to Configure and Use Oracle's Generic JMS Resource Adapter with OJMS | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-ojms/doc/how-to-gjra-with-ojms.html` | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-ojms/how-to-gjra-with-ojms.zip`
How to Configure and Use Oracle's Generic JMS Resource Adapter with IBM WebSphere MQ JMS | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-mqseries/doc/how-to-gjra-with-mqseries.html` | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-mqseries/how-to-gjra-with-mqseries.zip`
How to Configure and Use Oracle's Generic JMS Resource Adapter with Tibco Enterprise for JMS | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-tibco/doc/how-to-gjra-with-tibco.html` | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-tibco/how-to-gjra-with-tibco.zip`
How to Configure and Use Oracle's Generic JMS Resource Adapter with SonicMQ JMS | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-sonic/doc/how-to-gjra-with-sonic.html` | `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-sonic/how-to-gjra-with-sonic.zip`

Additional Documentation

The How-To documents at the following site provide additional information about OC4J 10g Release 3 (10.1.3) features, including feature overviews and code excerpts relevant to the feature.

`http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

## 3.2 JMS Configuration Overview

This section gives an overview of the following JMS configuration topics:

- JMS Configuration Sequence

- JMS Configuration File Structure

This OEMS document and the associated demos and How-To documents describe using the JMS Connector with the various supported resource providers, with emphasis on the OEMS JMS In-Memory and File-Based persistence options.

Additional discussions of these topics are available in other parts of this document. Also, a demo set of examples, including How-To documents and commented configuration files, is available at: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`. For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

### 3.2.1 JMS Configuration Sequence

This section outlines preparing the following components for JMS operation:

- Developing and Assembling the Application

- Configuring the Resource Provider

- Configuring the JMS Connector

You can, but are not required to, create matching sets of connection factories and destination objects, one set on the resource provider and the matching set on the JMS Connector. Alternatively, you can use "automatic destination wrapping" to avoid having to make a matching set of JMS Connector destinations.

#### 3.2.1.1 Developing and Assembling the Application

The tasks for developing and assembling your application to use JMS messaging are as follows:

- Write Code to Send and Receive Messages

- Declare Logical Names for JMS Resources

- Use Logical Names for JMS Resources

- Create and Declare an MDB Class

- Declare Message Destinations

- Link to Message Destinations

- Define the onMessage Transaction Attribute

- List the Application Modules

For details, see the How-To documents included in the demo set. For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

#### 3.2.1.2 Configuring the Resource Provider

Configuring the resource provider usually requires several rounds, arising out of the need for application component developers and application assemblers to have some connection factories and destinations to use for development. The development connection factories and destinations are often not the same connection factories and destinations used for deployment (since the development servers and production servers are often separate machines, and may be configured using different organization strategies, and may even use different resource providers). This document focuses on the production deployment.

When configuring a resource provider, you have to decide the following:

- How many and what type of resource provider connection factories will be needed to satisfy the application.

- How many and what type of resource provider destinations are needed to satisfy the application.

- Create RP Connection Factories

- Create RP Destinations

- Declare a Resource Provider Reference

See the How-to documents in the demo set for details. For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

#### 3.2.1.3 Configuring the JMS Connector

The introduction of the JMS Connector functionality in OEMS provides some degree of insulation from the specifics of the various resource providers. Based on the J2CA 1.5 specification, the JMS Connector acts as a compatibility layer and a value-added wrapper for the resource provider.

The tasks for configuring the JMS Connector are as follows:

- Settings in `ra.xml`.

- Create a JMS Connector Instance

- Create JMS Connector Connection Factories

- Create JMS Connector Destinations

For details, see the How-To documents included in the demo set. For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

#### 3.2.1.4 Additional Information and Examples

For detailed examples of the `oc4j-connectors.xml`, the `oc4j-ra.xml`, and the `ra.xml` files, go to: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

For detailed reference information on the JMS Connector XML files, go to Appendix A, OC4J Resource Adapter Configuration Files of the Oracle Containers for J2EE Resource Adapter Administrator's Guide.

The following links point to the document "How to Configure and Use Oracle's Generic JMS Resource Adapter with OracleAS JMS" and to the ZIP file containing the corresponding set of demo files. In these documents, the term "Generic JMS Resource Adapter" refers to the JMS Connector.

- "How to Configure and Use Oracle's Generic JMS Resource Adapter with OracleAS JMS" is available at:

  `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-oracleasjms/doc/how-to-gjra-with-oracleasjms.html`

- The ZIP file containing the corresponding set of demo files is available at:

  `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-gjra-with-oracleasjms/how-to-gjra-with-oracleasjms.zip`

### 3.2.2 JMS Configuration File Structure

This section points out the consistencies that must exist between the connection-factory and destination references and definitions in the JMS configuration files. Figure 3-1, "JMS Infrastructure" illustrates the references and definitions that must agree with each other.

Figure 3-1 JMS Infrastructure

Description of "Figure 3-1 JMS Infrastructure"

Figure 3-1 depicts the various types of links between the java source code, the application deployment descriptors, the resource adapter deployment descriptors, and the resource provider. At the tail of each arrow is a "link-reference", and at the head of each arrow is the "link-key" (name, JNDI location or Java interface) of the item being referenced. The textual representation of the link-key at the head and link-reference at the tail of any given arrow is always identical except where otherwise noted.

The files are:

- `ra.xml`

- `oc4j-ra.xml`

- `application.xml`

- `orion-application.xml`

- `oc4j-connectors.xml`

- `ejb-jar.xml`

- `orion-ejb-jar.xml`

- `application-client.xml`

- `orion-application-client.xml`

- `web.xml`

- `orion-web.xml`

The demo set includes expanded explanations of the relationships depicted in Figure 3-1, "JMS Infrastructure". For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

Download and unzip the relevant How-To-gjra-with-xxx.zip file, where xxx is the name of the relevant resource provider.

Open the relevant how-to-gjra-with-xxx.html document. The explanations in this section point to the section in the how-to document that explains the relationship.

The demo set also includes examples of Java code and deployment descriptor XML files.

Java Source Code

In J2EE applications, Java source code typically uses logical names to reference JMS resources. Logical names (references declared with `<resource-ref>` and `<message-destination-ref>` elements) are types of environment entries, and all environment entries are placed in the `java:comp/env/` JNDI subcontext. For details, see "Application Component Provider Task #3: Use Logical Names for JMS Resources" in the relevant How-To document.

Figure 3-1 depicts the two types of links from the Java source code to the J2EE application component deployment descriptors. The number of each description in the following list corresponds to a numbered link in the figure.

- 1 - The first link in a typical outbound connection factory "chain" is from the Java source code to a `<resource-ref>` element in a J2EE application component deployment descriptor. The link-reference is the location used in the JNDI lookup to obtain the JMS connection factory and must include the `java:comp/env` prefix. The link-key for a `<resource-ref>` element is the value of its `<res-ref-name>` subelement and must not include the java:comp/env prefix. Except for the `java:comp/env` prefix, the link-reference and link-key should be identical.

- 2 - The first link in a typical outbound destination chain is from the Java source code to a `<message-destination-ref>` element in a J2EE application component deployment descriptor. The link-reference is the location used in the JNDI lookup to obtain the JMS destination and must include the `java:comp/env` prefix. The link-key for a `<message-destination-ref>` element is the value of its `<message-destination-ref-name>` subelement and must not include the java:comp/env prefix. Except for the java:comp/env prefix, the link-reference and link-key should be identical.

J2EE application component deployment descriptors (application-client.xml, ejb-jar.xml, web.xml)

The logical names used by the Application Component Providers have a many-to-one relationship with physical destinations. The Application Assembler creates logical destinations which have a one-to-one relationship with physical destinations. The Application Assembler then needs to link the message destination references and MDBs created by the Application Component Providers to the message destinations created by the Application Assembler. This is done by adding `<message-destination-link>` elements that name the appropriate message destination. These links are not part of the destination chain, but instead provide information needed by the Deployer to complete the destination chain. For details, see "Application Assembler Task #2: Link to Message Destinations" in the relevant how-to-gjra-with-xxx.html document, where xxx is the name of the relevant resource provider.

Figure 3-1 depicts the two types of links fully contained within the J2EE application component deployment descriptor:

- 3 - For outbound messaging, this informational-only link is from a `<message-destination-ref>` element to a `<message-destination>` element, both in J2EE application component deployment descriptors (though not necessarily the same one). The link-reference is the value of the `<message-destination-link>` subelement. The link-key for a `<message-destination>` element is the value of its `<message-destination-name>` subelement. The link-reference may be prefixed with the name of the file containing the link-key followed by a # character. (This is only needed when different link-keys from different files happen to have the same exact value.) Except for the optional prefix, the link-reference and link-key should be identical.

- 4 - For MDB/inbound messaging, this informational-only link is from a `<message-driven>` element to a `<message-destination>` element, both in J2EE application component deployment descriptors (though not necessarily the same one). The link-reference is the value of the `<message-destination-link>` subelement. As previously mentioned, the link-key for a `<message-destination>` element is the value of its `<message-destination-name>` subelement. The link-reference may be prefixed with the name of the file containing the link-key followed by a # character. (This is only needed when different link-keys from different files happen to have the same exact value.) Except for the optional prefix, the link-reference and link-key should be identical.

OC4J-specific application component deployment descriptors (orion-application-client.xml, orion-ejb-jar.xml, orion-web.xml)

Figure 3-1 depicts the following seven types of references from the OC4J-specific application component deployment descriptor:

- Application components declare logical names for connection factories in J2EE application component deployment descriptors. The deployer then maps those logical names to JMS Connector connection factories.

  For details and examples, see "Deployer Task #1: Map Logical Connection Factories to RA ConnectionFactories" in the relevant How-To document.

  The figure depicts the two types of connection factory links provided by the `<resource-ref-mapping>` element.

  - 6 - The second link in a typical outbound connection factory chain is from a `<resource-ref-mapping>` element in an OC4J-specific application component deployment descriptor back to a `<resource-ref>` element in a J2EE application component deployment descriptor. The link-reference is the value of the `name` attribute of the `<resource-ref-mapping>` element. As mentioned previously, the link-key for a `<resource-ref>` element is the value of its `<res-ref-name>` subelement.

  - 5 - The third link in a typical outbound connection factory chain is from a `<resource-ref-mapping>` element in an OC4J-specific application component deployment descriptor to a `<connector-factory>` element in an `oc4j-ra.xml` file. The link-reference is the value of the location attribute of the `<resource-ref-mapping>` element. The link-key for a `<connector-factory>` element is the value of its location attribute (which is also the JNDI location where the resource adapter connection factory defined by the given `<connector-factory>` element will be bound).

- Application components declare logical names for destinations in J2EE application component deployment descriptors. The deployer then maps those logical names to JMS Connector destinations, making use of any information provided by the Application Assembler in the form of `<message-destination-link>`s and `<message-destination>`s.

  For each `<message-destination>`, the deployer must map all `<message-destination-ref>`s and MDBs linked to that `<message-destination>` to the same destination.

  For details and examples, see "Deployer Task #2: Map Logical Destinations to RA Destinations" in the relevant How-To document.

  The figure depicts the two types of destination links provided by the `<destination-ref-mapping>` element:

  - 8 - The second link in a typical outbound destination chain is from a `<message-destination-ref-mapping>` element in an OC4J-specific application component deployment descriptor back to a `<message-destination-ref>` element in a J2EE application component deployment descriptor. The link-reference is the value of the `name` attribute of the `<message-destination-ref-mapping>` element. As mentioned previously, the link-key for a `<message-destination-ref>` element is the value of its `<message-destination-ref-name>` subelement.

  - 7 - The third link in a typical outbound destination chain is from a `<message-destination-ref-mapping>` element in an OC4J-specific application component deployment descriptor to an `<adminobject-config>` element in an `oc4j-connectors.xml` file. The link-reference is the value of the location attribute of the `<message-destination-ref-mapping>` element. The link-key for an `<adminobject-config>` element is the value of its location attribute (which is also the JNDI location where the resource adapter destination defined by the given `<adminobject-config>` element will be bound).

- For each MDB, the deployer must indicate the JMS Connector instance, connection factory and destination that should be used to meet the MDB's inbound messaging requirements.

  For details and examples, see "Deployer Task #2: Map Logical Destinations to RA Destinations" and "Deployer Task #3: Configure the MDB" in the relevant document.

  Figure 3-1 depicts the three types of inbound messaging links from the `orion-ejb-jar.xml` file to the `oc4j-connectors.xml` and `oc4j-ra.xml` files:

  - 9 - The link that tells the container which JMS Connector instance should be used to handle a given MDB's inbound messaging needs is from the MDB's `<message-driven-deployment>` element in an `orion-ejb-jar.xml` file to the JMS Connector instance's `<connector>` element in an `oc4j-connectors.xml` file. The link-reference is the value of the resource-adapter attribute of the `<message-driven-deployment>` element. The link-key for a `<connector>` element is the value of its `name` attribute (which is also the JNDI location where the resource adapter instance defined by the given `<connector>` element will be bound).

  - 10 - For MDB/inbound messaging, a single link is used instead of the three connection factory links described to this point. This link is from a `<message-driven-deployment>` element in an `orion-ejb-jar.xml` file to a `<connector-factory>` element in an `oc4j-ra.xml file`. The link-reference is the value of the `<message-driven-deployment>`'s `ConnectionFactoryJNDIName` config property. As mentioned previously, the link-key for a `<connector-factory>` element is the value of its location attribute (which is also the JNDI location where the resource adapter connection factory defined by the given `<connector-factory>` element will be bound). Note that this links to the same place as the third link in the outbound case, and the rest of the connection factory chain is the same for both inbound and outbound messaging.

  - 11 - For MDB/inbound messaging, a single link is used instead of the three destination links described to this point. This link is from a `<message-driven-deployment>` element in an `orion-ejb-jar.xml` file to an `<adminobject-config>` element in an `oc4j-connectors.xml` file. The link-reference is the value of the `<message-driven-deployment>`'s `DestinationName` config property. As mentioned previously, the link-key for an `<adminobject-config>` element is the value of its location attribute (which is also the JNDI location where the resource adapter destination defined by the given `<adminobject-config>` element will be bound). Note that this links to the same place as the third link in the outbound case, and the rest of the destination chain is the same for both inbound and outbound messaging.

oc4j-connectors.xml

JMS Connector destinations act as wrappers for RP destinations. In order for the JMS Connector to look up an RP destination, the JMS Connector needs to know the JNDI location of the RP destination.

For details and examples, see "Resource Adapter Task #4: Create RA Destinations" in the relevant How-To document. For information on creating resource provider destinations, see "Configuring the Resource Provider" in the relevant How-To document.

Figure 3-1 depicts the two types of links which together tie JMS Connector destinations defined in `oc4j-connectors.xml` to RP destinations:

- 12 - The final segment of the destination chain is from an `<adminobject-config>` element in an `oc4j-connectors.xml` file (which defines a JMS Connector destination) to a resource provider destination, and is composed of two parallel links. The first link is from the `<adminobject-config>` element to a `<resource-provider>` element in an individual application's `orion-application.xml` file (or the default application's `application.xml` file). The link-reference is the value of the `<adminobject-config>`'s `resourceProviderName` config property. The link-key for a `<resource-provider>` element is the value of its `name` attribute (which is also the JNDI location under `java:comp/resource` where the resource provider reference defined by the `<resource-provider>` element will be bound - the providerName).

- 13 - The second link completes the connection from the `<adminobject-config>` element to the resource provider destination. The link-reference is the value of the `<adminobject-config>`'s `jndiName` config property. The link-key is the JNDI location of the RP destination within the resource provider's JNDI context (the resourceName). Together, these two links provide the JMS Connector destination with the full JNDI location

       java:comp/resource/providerName/resourceName

  of the RP destination.

oc4j-ra.xml

JMS Connector connection factories act as wrappers for RP connection factories. In order for the JMS Connector to look up an RP connection factory, the JMS Connector needs to know the JNDI location of the RP connection factory.

For details and examples, see "Resource Adapter Task #3: Create RA Connection Factories" in the relevant How-To document. For information on creating resource provider connection factories (but not for the OEMS JMS Database persistence option since all these connection factories are automatically pre-created, see "Configuring the Resource Provider" in the relevant How-To document.

Figure 3-1 depicts three types of links that help define the implementation for JMS Connector connection factories defined in `oc4j-ra.xml` and tie them to RP connection factories:

- 15 - In theory this link ties a `<connector-factory>` element in an `oc4j-ra.xml` file (which defines a JMS Connector connection factory) to a `<connector>` element in an `oc4j-connectors.xml` file (which defines an JMS Connector instance). In practice this link may not actually be used, but for future compatibility it should be set as follows: The link-reference is the value of the `connector-name` attribute of the `<connector-factory>` element. As previously mentioned, the link-key for a `<connector>` element is the value of its `name` attribute (which is also the JNDI location where the JMS Connector instance defined by the given `<connector>` element will be bound).

- 16 - The final segment of the connection factory chain is from a `<connector-factory>` element in an `oc4j-ra.xml` file (which defines a JMS Connector connection factory) to an RP connection factory, and is composed of two parallel links. The first link gives the JNDI location under `java:comp/resource` where the resource provider reference is bound (the providerName). It's link-reference is located in the `ra.xml` file - see the description for arrow #18. The second link completes the connection from the `<connector-factory>` element to the resource provider connection factory. The link-reference is the value of the `<connector-factory>`'s `jndiLocation` config property. The link-key is the JNDI location of the RP connection factory within the resource provider's JNDI context (the resourceName). Together, these two links provide the JMS Connector connection factory with the full JNDI location

       java:comp/resource/providerName/resourceName

  of the RP connection factory. NOTE: This link is actually an optional over-ride. (See description for arrow #17.) By convention this over-ride is always set (even if its value is the same as the value it is overriding).

- 14 - The implementation details for a JMS Connector connection factory (a `<connector-factory>` element in an `oc4j-ra.xml` file) are defined by linking the `<connector-factory>` element to a `<connection-definition>` element in an `ra.xml` file. The link-reference is the value of the `<connector-factory>`'s `<connectionfactory-interface>` subelement. The link-key for a `<connection-definition>` element is the value of its `<connectionfactory-interface>` subelement.

ra.xml

Much of the content in the `ra.xml` file does not need to be changed when using the JMS Connector. (The reason for this is that the `ra.xml` file is based on a J2EE Connector Architecture 1.5 schema file, which is a generic schema intended to work with many types of resource adapters, including non-JMS resource adapters.)

For details and examples, see "Resource Adapter Task #1: Customize the ra.xml File" in the relevant How-To document.

Figure 3-1 depicts two types of links that define default JMS Connector connection factory settings in `ra.xml`:

- 18 - This is the first link of the final segment of the connection factory chain. (See description for arrow #16.) This link is from a `<resourceadapter>` element in an `ra.xml` file to a `<resource-provider>` element in an individual application's `orion-application.xml` file (or the default application's `application.xml` file). The link-reference is the value of the `<resourceadapter>`'s `resourceProviderName` config property. As mentioned previously, the link-key for a `<resource-provider>` element is the value of its `name` attribute (which is also the JNDI location under `java:comp/resource` where the resource provider reference defined by the `<resource-provider>` element will be bound). NOTE: The link-reference value in the `ra.xml` file is just a default, and for any given JMS Connector instance it may be overridden using the `<connector>`'s `resourceProviderName` config property in the JMS Connector instance's `oc4j-connectors.xml` file. The over-ride is generally not required and is not depicted with an arrow in the figure.

- 17 - This link acts as a default when a `<connector-factory>` linked to a `<connection-definition>` (see description for arrow #14) does not include a `jndiLocation` config property (see description for arrow #16). The link-reference is the value of the `<connection-definition>`'s `jndiLocation` config property. The link-key is the JNDI location of the RP connection factory within the resource provider's JNDI context

### 3.2.3 Bypassing the JMS Connector for Application Clients

Most of the features provided by the JMS Connector are not applicable to application clients. In order to keep application clients as light-weight as possible, you may choose to not use the JMS Connector with application clients. An application client that is not using the JMS Connector can communicate with application components that are using the JMS Connector so long as the same underlying resource provider (RP) destination is used by both components. Bypassing the JMS Connector is accomplished by referencing resource provider resources instead of JMS Connector resources in the `orion-application-client.xml` file:

1. Bypass JMS Connector Connection Factories -

   For each `<resource-ref-mapping>` element, make the value of its `location` attribute be

        java:comp/resource/providerName/resourceName

   where providerName is equal to the link-key for arrow #18 in Figure 3-1, "JMS Infrastructure" and resourceName is equal to the link-key for arrow #16 in Figure 3-1. This replaces arrows #6, #18 and #16 in Figure 3-1 with a direct link to the RP connection factory, bypassing the JMS Connector's `oc4j-ra.mxl` and `ra.xml` files.

2. Bypass JMD Connector Destinations -

   For each `<message-destination-ref-mapping>` element, make the value of its `location` attribute be

        java:comp/resource/providerName/resourceName

   where providerName is equal to the link-key for arrow #12 in Figure 3-1, "JMS Infrastructure" and resourceName is equal to the link-key for arrow #13 in Figure 3-1. This replaces arrows #7, #12 and #13 in Figure 3-1 with a direct link to the RP destination, bypassing the JMS Connector's `oc4j-connectors.xml` file.

Some third-party tools or libraries that access JNDI directly may have rigid location limits and/or validation rules that do not allow for the `java:comp/resource` syntax and/or naming peculiarities of specific resource providers, such as the `Queues/` prefix and other prefixes used by OEMS JMS Database option. In that situation, the JMS Connector should not be bypassed. (In general this limitation does not apply to the OEMS JMS In-Memory and File-Based options. This is because, for these resources, the `resourceName` can be used in a JNDI lookup by itself. That is, the

     java:comp/resource/providerName/resourceName

prefix is purely optional when using OEMS JMS In-Memory or File-Based options.)

An application must not pass JMS Connector destinations to any object derived from an RP connection factory, and must not pass RP destinations to any object derived from a JMS Connector connection factory. The JMS Connector automatically manages the conversion from one destination type to the other for the `JMSDestination` and `JMSReplyTo` header fields for all sent, received, and browsed messages. For example, if an application client that is not using the JMS Connector sets the `JMSReplyTo` header field for an RP message to an RP destination and sends the message, and another application component that is using the JMS Connector receives the message and reads the `JMSReplyTo` header field, then the receiver will get a compatible JMS Connector message and JMS Connector destination that wrap the original RP message and RP destination. There is no automatic conversion for any other case. For example, if that scenario were repeated, but instead of sending the message directly it was sent as the body of an ObjectMessage, then when the receiver extracted the body of the ObjectMessage it would get an RP message instead of an JMS Connector message, and the `JMSReplyTo` header field of that RP message would contain an RP destination rather than a JMS Connector destination.

## 3.3 Resource Providers

The underlying connection factories and destinations that application clients use to send and receive JMS messages are resource provider objects. In 10.1.3, OC4J uses the JMS Connector to plug in the OEMS JMS (In-Memory, File-Based, and Database), IBM MQ, TIBCO, and Sonic resource providers.

But ultimately the destinations and connection factories must be created in the resource provider.

In general, use the following steps to configure a resource provider:

- Declare Resource Provider References

- Create RP Connection Factories

- Create RP Destinations

Each JMS provider requires its own procedure for configuring the provider and creating connection factories and destination objects. For resource providers other than OEMS JMS, refer to the documentation for that provider.

- OEMS JMS In-Memory and File-Based resource provider connection factories and destinations are created and bound to JNDI in the `jms.xml` file. These OEMS JMS persistence options are discussed in "OEMS JMS In-Memory and File-Based Persistence", starting.

- The OEMS JMS Database persistence option connection factories and destinations are created using SQL procedures. The OEMS JMS Database option is discussed in "OEMS JMS Database Persistence", starting.

### 3.3.1 Declaring Resource Provider References

A client can use one or more different JMS resource providers, each with its own resource adapter, choosing according to the integration and quality-of-service (QOS) features desired.

You declare the references to the resource provider that you will use in one or more `<resource-provider>` elements of the `orion-application.xml` file and/or the `application.xml` file.

- OEMS JMS In-Memory and File-Based Persistence—These two OEMS JMS persistence options are installed with OC4J.

- OEMS JMS Database Persistence—The OEMS JMS Database persistence option is a feature of the Oracle database and is based on the Streams Advanced Queuing (AQ) messaging system.

  The benefits of the OEMS JMS Database persistence option are as follows:

  - It is backed by the Oracle database.

  - OEMS JMS Database persistence and other Oracle database transactions can be used together in one-phase commit transactions.

  - It also provides access to extra features provided by AQ including interoperability with PL/SQL and OCI.

- Using Third-Party JMS Providers—You can integrate with the following third-party JMS providers:

  - WebSphere MQ for JMS versions 6.0 and 5.3 resource provider

  - TIBCO Enterprise for JMS version 3.1.0

  - SonicMQ 6.0

Use one of the following files to declare a resource provider reference:

- To make a resource provider reference visible to all applications (global), then use the global `application.xml` file.

- To make a resource provider reference visible only to a single application (local), then use the `orion-application.xml` file specific to the application.

Add the following code to the appropriate XML file (as listed above):

    <resource-provider class="providerClassName" name="providerName">
         <description>description </description>
         <property name="name" value="value" />
    </resource-provider>

For the `<resource-provider>` attributes, configure the following:

- `class`—The name of the resource provider class.

  - For the OEMS JMS In-Memory and File-Based option, use: `com.evermind.server.jms.Oc4jResourceProvider`

  - For the OEMS JMS Database option, use: `oracle.jms.OjmsContext`

  - For all third party resource providers, use: `com.evermind.server.deployment.ContextScanningResourceProvider`

- `name`—A name by which to identify the resource provider. This name is used to map the resource provider's JNDI context in the application's JNDI as:

      java:comp/resource/providerName/

The subelements of the `<resource-provider>` are configured as follows:

- `<description>` subelement—A description of the specific resource provider.

- `<property>` subelement—The `name` and `value` attributes are used to identify parameters provided to the resource provider. The `name` attribute identifies the name of the parameter, and its value is provided in the `value` attribute.

Before an application or a resource adapter running in OC4J can access a resource provider, a resource provider reference must be declared with the `<resource-provider>` element. The resource provider reference holds miscellaneous data (for example, the class name described below) that OC4J uses to interact with the resource provider. The resource provider reference also provides a JNDI subcontext through which resource provider resources can be accessed. The resource provider reference (and said JNDI access) can be made local to the application by placing it in `orion-application.xml`, or available to all applications by placing it in `%ORACLE_HOME%/j2ee/home/config/application.xml`.

The two pieces of information that you must provide whenever declaring a resource provider reference are the name you wish to use for the resource provider reference and the Java class that implements the resource provider interface.

The resource provider reference maps the resource provider's JNDI context, which contains resource provider connection factories and resource provider destinations, to a JNDI subcontext accessible by the application and, more importantly, the JMS Connector. The reason it is more important for the JMS Connector to be able to access resource provider resources than for the application to be able to do so is that, when using a JMS Connector, the application need not (and in general should not) directly look up or use any resource provider resources. That JNDI subcontext is `java:comp/resource/providerName` where `providerName` is the name of the resource provider reference.

The demo set at `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html` includes examples of declaring resource provider references. For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

Download and unzip the How-To-gjra-with-xxx.zip file, where xxx is the name of the relevant resource provider.

Drill down to the following file: `/src/META-INF/orion-application.xml`.

For more detail, search for "Configuring the Resource Provider" in the relevant How-To document.

In the demo, the data source and the resource provider are declared local to the application. If the data source definition is placed in `$J2EE_HOME/config/data-sources.xml` and the resource-provider definition is placed in `$J2EE_HOME/config/application.xml`, then they are visible to all applications. (Only the demo for the OEMS JMS Database Persistence provider requires or includes a data source.)

The following sections give more detail on declaring the resource provider reference for each resource provider supported by OC4J, including the Java class and an example resource provider reference name for each:

- OEMS JMS In-Memory and File-Based Persistence

- OEMS JMS Database Persistence

- Declaring the OEMS JMS Database Reference

- Declaring an IBM WebSphere MQ Resource Provider Reference

- Declaring a TIBCO Enterprise Message Service Resource Provider Reference

- Declaring a SonicMQ Resource Provider Reference

### 3.3.2 OEMS JMS In-Memory and File-Based Persistence

The OEMS JMS In-Memory and File-Based options provide the following features:

- Complies with the JMS 1.1 specification.

- Is compatible with the J2EE 1.4 specification.

- Offers a choice between in-memory or file-based message persistence.

- Provides an exception queue for undeliverable messages.

Note: If you see the term "OC4J JMS" or "OracleAS JMS" in the Application Server Control Console, in the MBeans, or in the sample code, this refers to the OEMS JMS In-Memory and File-Based persistence options.

This section covers the following topics:

- Configuring Destination Objects and Connection Factories

- Configuring in the Application Server Control Console

- Configuration Elements

- Configuration Using jms.xml

- Configuring Ports

- Sending and Receiving JMS Messages

- JMS Utility

- Configuring File-Based Persistence

- Abnormal Termination

- Predefined Exception Queue

- Message Paging

- Configuration Elements

- JMS Configuration Properties

#### 3.3.2.1 Configuring Destination Objects and Connection Factories

Destination objects can be queues or topics. The OEMS JMS In-Memory and File-Based options are already installed with OC4J, so the only configuration necessary is for the custom destination objects and connection factories for your applications to use.

The primary tool for configuring Destination objects and connection factories is the Application Server Control Console. You can also edit the XML files directly.

##### 3.3.2.1.1 Default Destination Objects and Connection Factories

The defaults are useful as follows:

- The connection factories can be copied and used as templates for connection factories that you create. The default connection factories can also be used without modification in production.

- The destinations can be copied and used as templates for destinations that you create. The default destinations should NOT be used in production.

Six default connection factories are created for the different combinations of XA (global transaction enabled), non-XA, and various JMS interfaces. Your applications can use these connection factories without your having to add them in the Application Server Control Console or the `jms.xml` file. The only reason to define a new connection factory is to specify non default values for one or more of the optional attributes of `connection-factory` elements.

The default connection factory objects are created internally by OC4J, which binds them to the default JNDI locations within the OC4J server where the JMS connection is created.

The following default connection factories are created, even though they are not explicitly defined in the `jms.xml` file. It is safer to treat these as reserved JNDI locations and to use other JNDI locations when you create custom connection factories.

| XA | non-XA
--- | --- | ---
Default Queue Connection Factory | `jms/XAQueueConnectionFactory` | `jms/QueueConnectionFactory`
Default Topic Connection Factory | `jms/XATopicConnectionFactory` | `jms/TopicConnectionFactory`
Default Unified Connection Factory | `jms/XAConnectionFactory` | `jms/ConnectionFactory`

Default destinations are as follows:

Default | Destination
--- | ---
Default Queue | `jms/demoQueue`
Default Topic | `jms/demoTopic`

#### 3.3.2.2 Configuring in the Application Server Control Console

The Application Server Control Console is the primary tool for configuring the OEMS JMS In-Memory and File-Based persistence option connection factories and destination objects. For each destination object, you must specify its name, location, and destination type (queue or topic).

Path to the Application Server Control Console:

OC4J:Home > Administration tab > Services > JMS Providers > Go To Task Configure OracleAS JMS > Select the appropriate tab.

Table 3-2, Configuration Elements table describes the OracleAS JMS resource provider configuration elements and their attributes.

#### 3.3.2.3 Configuration Elements

Table 3-2 defines the configuration elements and shows where to make the settings in the Application Server Control Console, in the MBeans, and in the `jms.xml` file.

Table 3-2 Configuration Elements

Console and MBean Setting Locations | Element(s) of jms.xml | Description and Attributes
--- | --- | ---
The `JMSAdministrator` MBean enables you to specify the server host name and port, and multiple related attributes and operations. Path to the JMSAdministrator MBean: OC4J:Home > Administration tab > Task Name: JMX. System MBean Browser. > Go To Task > Drill down: J2EEDomain:oc4j, J2EEServer:standalone, JMSAdministratorResource, `"JMSAdministrator"` | `<jms-server>` | The root element of the server configuration. The `<jms-server>` element takes the following attributes: `host` - The host name defined in a `String` (DNS or dot-notation host name) to which this server should bind. By default, the server binds to `0.0.0.0` (also known as `[ALL]` in the configuration file). Optional. `port` - The port defined as an `int` (valid TCP/IP port number) to which this server should bind. The default setting is `9127`. This setting applies only to the standalone configuration of OC4J. In the Oracle Application Server configuration, the port setting in the configuration file is overridden by command-line arguments that are used (by, for example, OPMN and others) when starting the OC4J server. Optional.
Create a resource provider destination and specify its attributes on the `Add Destinations` page. Path to the Add Destinations page: OC4J:Home > Administration tab > Task Name: Services.JMS Providers > Go To Task > Destinations tab > Create New | `<queue>` | This element configures queues. The queues are available when OC4J starts up, and are available for use until the server is restarted or reconfigured. You can configure zero or more queues in any order. Any newly-configured queue is not available until OC4J is restarted. The `<queue>` element takes the following attributes: `name` - This required attribute is the provider-specific name (`String`) for the queue. The name can be any valid non empty string (with white space and other special characters included, although this is not recommended). The name specified here can be used in `Session.createQueue()` to convert the provider-specific name to a JMS queue. It is invalid for two destinations to specify the same name. There is no default. `location` - This required attribute states the JNDI location (`String`) where the queue is bound. The value should follow the JNDI rules for valid names. `persistence-file` - An optional path and filename (`String`). The path for the `persistence-file` attribute is either an absolute path of the file or a path relative to the `persistence` directory defined in `application.xml`. The default path is `J2EE_HOME``/persistence/<group>` for Oracle Application Server environments and `J2EE_HOME``/persistence` for standalone environments. Each queue and topic must have its own persistence file name. You must not have two objects writing to the same persistence file. The `persistence-file` attribute is discussed further at "Persistence Recovery".
Create a topic destination and specify its attributes on the `Add Destinations` page. Path to the Add Destinations page: OC4J:Home > Administration tab > Task Name: Services.JMS Providers > Go To Task > Destinations tab > Create New | `<topic>` | This element configures a topic. The topics are available when OC4J starts up, and are available for use until the server is restarted or reconfigured. You can configure zero or more topics in any order. Any newly configured topic is not available until OC4J is restarted. The `<topic>` element takes the following attributes: `name` - This required attributes is the provider-specific name (`String`) for the topic. The name can be any valid non empty string (with white space and other special characters included, although this is not recommended). The name specified here can be used in `Session.createTopic()` to convert the provider-specific name to a JMS topic. It is invalid for two destinations to specify the same name. There is no default. `location` - This required attribute states the JNDI location (`String`) where the topic is bound. The value should follow the JNDI rules for valid names. There is no default. `persistence-file` - An optional path and filename (`String`). The path for the `persistence-file` attribute is either an absolute path of the file or a path relative to the `persistence` directory defined in `application.xml`; the default path is `J2EE_HOME``/persistence/<group>` for Oracle Application Server environments and `J2EE_HOME``/persistence` for standalone environments. Each queue and topic must have its own persistence file name. You must not have two objects writing to the same persistence file. The `persistence-file` attribute is discussed further at "Persistence Recovery".
The `Description` field is on the `Add Destination` page where you create the topic or queue to which the description applies. | `<description>` | A sub-element of `<queue>` or `<topic>`. A user-defined string to remind the user for what the queue or topic is used. Optional.
Create a connection factory and specify its attributes on the `Add Connection Factory` page. Path to Add or Edit a Connection Factory: OC4J:Home > Administration tab > Task Name: Services.JMS Providers > Go To Task > Connection Factories tab > Create New or Edit Properties | `<connection-factory>` or `<queue-connection-factory>` or `<topic-connection-factory>` | Connection factory configuration. A connection factory element takes the following attributes: `location` - Required. The JNDI location to which the connection factory is bound. The value must follow JNDI rules for valid names. `host` - Optional. The fixed OC4J host to which this connection factory will connect. By default, a connection factory uses the same host as configured for the `jms-server` element. Non default values can be used to force all JMS operations to be directed to a specific OC4J JVM, bypassing any locally available OC4J servers and other Oracle Application Server or clustered configurations. Optional, string, DNS or dot notation host name. Default = `ALL` `port` - Optional. The fixed port to which this connection factory connects. By default, a connection factory uses the same port as configured for the `jms-server` element (or the value of the port that was specified for Oracle Application Server or clustered configurations on the command line). Non default values can be used to force all JMS operations to be directed to a specific OC4J JVM, bypassing any locally available servers and other Oracle Application Server or clustered configurations. Optional, int, valid TCP/IP port number. Default = `9127`. `username` - Optional. The user name for the authentication of JMS default connections created from this connection factory. That is, if an application creates a connection and neither the application nor the `oc4j-ra.xml` file specifies a `username/password`, then the `username` and `password` attributes from this element will be used. The user name itself must be properly created and configured with other OC4J facilities. Optional, string. Default = the empty string. `password` - Optional. The password for the authentication of JMS default connections created from this connection factory. The password itself must be properly created and configured with other OC4J facilities. The property `password` attribute supports password indirection. For more information, refer to the Oracle Containers for J2EE Security Guide. Optional, string. Default = the empty string. `clientID` - Optional. The administratively configured, fixed JMS `clientID` for connections created from this connection factory. If no `clientID` is specified, then the default is an empty string, which can also be programmatically overridden by client programs, according to the JMS specification. The `clientID` is used only for durable subscriptions on topics; its value does not matter for queue and nondurable topic operations. Optional, string. Default = the empty string.
Create an XA-enabled connection factory and specify its attributes on the `Add Connection Factory` page. Path to Add or Edit a Connection Factory: OC4J:Home > Administration tab > Task Name: Services.JMS Providers > Go To Task > Connection Factories tab > Create New or Edit Properties | `<xa-connection-factory>` or `<xa-queue-connection-factory>` or `<xa-topic-connection-factory>` | XA variants of connection factory configuration. The XA connection factory elements take the same attributes as the non-XA connection factory elements, which are described in the previous row.
| `<log>` | Enables logging of the JMS activity in either file or ODL format. See the section "Enabling OC4J Logging" in the Oracle Containers for J2EE Configuration and Administration Guide for information on logging.
Edit system properties settings in the `JMSAdministratorResource MBean`. Path to system properties settings in JMSAdministratorResource MBean: OC4J:Home > Administration tab > Task Name: JMX.System MBean Browser. > Go To Task > Drill down: J2EEDomain:oc4j, J2EEServer:standalone, JMSAdministratorResource, "JMSAdministrator" > Operations tab > setConfigProperty | `<config-properties>` | Sets system properties. The settings are persisted to the `jms.xml` file. `<config-property>` - Subelement of `<config-properties>`. These settings are discussed in "JMS Configuration Properties".

#### 3.3.2.4 Configuration Using jms.xml

The OEMS JMS In-Memory and File-Based configuration settings are persisted in the `jms.xml` file. The settings in `jms.xml` include:

- Connection factories

- Destinations

- JMS Router jobs

- Global configuration

Note: Remember that you must restart the OC4J instance to enable configuration changes made directly in the XML files.

The following example shows the structure of elements under `<jms-server>` within the `jms.xml` file. This example configures the following destinations and connection factories:

- The queue "MyQueue" at JNDI location `jms/MyQueue`

- The topic "MyTopic" at JNDI location `jms/MyTopic`

- A connection factory (unified) at JNDI location `jms/Cf`

- A queue connection factory at JNDI location `jms/Qcf`

- An XA topic connection factory at JNDI location `jms/xaTcf`.

    <jms>
      <jms-server>

        <queue  name="MyQueue" location="jms/MyQueue" persistence-file="/tmp/MyQueue">
           <description>The demo queue. </description>
        </queue>

        <topic name="MyTopic" location="jms/MyTopic" persistence-file="/tmp/MyTopic">
          <description>The demo topic. </description>
        </topic>

        <connection-factory location="jms/Cf">
        </connection-factory>

        <queue-connection-factory location="jms/Qcf">
        </queue-connection-factory>

        <xa-topic-connection-factory location="jms/xaTcf"
            username="foo" password="bar" clientID="baz">
        </xa-topic-connection-factory>

        <log>
          <file path="../log/jms.log" />
        </log>

        <config-properties>
          <config-property name="oc4j.jms.debug" value="true">
          </config-property>
        </config-properties>

      </jms-server>

       <jms-router>
          <!-- JMS router configuration is shown in the
          "JMS Router Configuration in jms.xml" section.
          -->
       </jms-router>

    </jms>

A detailed example of the element structure under `<jms-router>` is available at "JMS Router Configuration in jms.xml".

#### 3.3.2.5 Configuring Ports

In a standalone OC4J instance, you can set the port range in the `JMSAdministrator` MBean. You must restart the OC4J instance for your changes to take effect. This restart requirement is a special case for port settings.

In the full Oracle Application Server environment (managed), use the Application Server Control Console to configure the port range.

Path to configure the port range in the Application Server Control Console:

OC4J:Home > Administration tab > Task Name: JVM Properties > JMS Ports

#### 3.3.2.6 Sending and Receiving JMS Messages

The code for sending and receiving JMS messages is not dependent on the JMS Connector or the resource providers involved.

This example is from the `MyChannel.java` file in the demo sets at: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

Drill down to the following file: `/src/common/MyChannel.java`

In the demo, `MyChannel.java` is the only class that sends or receives JMS messages. All other classes call `MyChannel` to do sends and receives. `MyChannel` is the same for all of the different resource providers. In fact, all of the .java source is the same for all of the resource providers except for some comments in `Player.java` that explain alternate JNDI locations (not based on logical names) that may be used for looking up connection factories and destinations

For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

       public MyChannel(String connectionFactoryName, String destinationName) throws Exception {

            Context ctx = new InitialContext();

            // Get the destination.
            Destination destination = (Destination) ctx.lookup(destinationName);

            // Get the connection factory.
            ConnectionFactory cf = (ConnectionFactory)
     ctx.lookup(connectionFactoryName);

            // Use the connection factory to create a connection.
            connection = cf.createConnection();

            // Start the connection.
            connection.start();

            // Use the connection to create a session.
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

            // Use the session and destination to create a message producer and a message consumer.
            producer = session.createProducer(destination);
            consumer = session.createConsumer(destination);
        }

        /**
         * Send message.
         * prerequisite: channel is open
         * @param obj object to be sent
         */
        public void send(Serializable obj) throws JMSException {

            // Use the session to create a new message.
            ObjectMessage msg = session.createObjectMessage(obj);

            // Use the message producer to send the message.
            producer.send(msg);
            System.out.println("Sent message: " + obj);
        }

        /**     * Receive message (wait forever).
         * prerequisite: channel is open
         * @return object which was received in message, or <code>null</code> if no message was received
         */
        public Serializable receive() throws JMSException {

            // Use the message consumer to receive a message.
            ObjectMessage msg = (ObjectMessage) consumer.receive();

            System.out.println("Got message: " + msg.getObject());
            return msg.getObject();
        }

        /**
         * Receive message (wait a while).
         * prerequisite: channel is open
         * @param timeout maximum time (in milliseconds) to wait for a message to arrive
         * @return object which was received in message,
         * or <code>null</code> if no message was received     */
        public Serializable receive(long timeout) throws JMSException {

            // Use the message consumer to receive a message (if one comes in time).
            ObjectMessage msg = (ObjectMessage) consumer.receive(timeout);

            if (msg == null) return null;
            System.out.println("Got message: " + msg.getObject());
            return msg.getObject();
        }

        /**
         * Close channel.
         * prerequisite: channel is open
         * Once a MyChannel object is closed, it may no longer be used to send or receive
         * messages.
         */
        public void close() throws JMSException {

            // Close the connection (and all of its sessions, producers and consumers).
            connection.close();
        }

        private Connection connection;
        private Session session;
        private MessageProducer producer;
        private MessageConsumer consumer;
    }

#### 3.3.2.7 JMS Utility

In this release, JMS Utility functionality is available as attributes and operations on various MBeans, replacing the deprecated command line interface of previous releases.

JMS Utility functionality resides on the following MBeans:

- The `JMSAdministrator` MBean - Path:

  OC4J:Home > Administration tab > Task Name: JMX.System MBean Browser > Go To Task > Drill down: J2EEDomain:oc4j, J2EEServer:standalone, JMSAdministratorResource, "JMSAdministrator"

- The `JMS` MBean - Path:

  OC4J:Home > Administration tab > Task Name: JMX.System Bean Browser > Go To Task > Drill down: J2EEDomain:oc4j, J2EEServer:standalone, JMSResource, "JMS"

- Various JMSDestinationResource MBeans - Path:

  OC4J:Home > Administration tab > Task Name: JMX.System MBean Browser > Go To Task > Drill down: J2EEDomain:oc4j, J2EEServer:standalone, JMSResource, "JMS", JMSDestinationResource > Select the MBean that represents the desired destination.

Table 3-3 JMS Utility

MBean Implementation | Previous Command Line Command | Description
--- | --- | ---
`configProperties` attribute in the `JMSAdministrator` MBean | `knobs` | Display all available system properties (shown in Table 3-4) and their current settings.
Statistics tab in the `JMS` MBean | `stats` | The following OEMS JMS In-Memory and File-Based statistics are available through the `JMS` MBean: `activeHandlers` `activeConnections` `pendingMessageCount` `messageDequeued` `messageExpired` `messageCommitted` `messageRolledBack` `messageEnqueued` `messageRecovered` `messageDiscarded` `messagePagedIn` `messageCount`
`validateSelector` operation on the `JMSAdministrator` Mbean. | `check <selector>` | Check validity of the specified JMS message selector. The operation takes the argument `selector`.
`areSelectorsEqual` operation on the `JMSAdministrator` Mbean. | `check <sel1> <sel2>` | Check if two specified selectors are treated as equivalent. This is useful for reactivating durable subscriptions. The operation takes the arguments: `sel1` and `sel2`.
`subscribe` operation on all JMSDestinationResource MBeans whose domain = `topic` | `subscribe` | Creates a durable subscription on the destination. This replaces existing, inactive durable subscriptions. The operation takes the following arguments: `name` - name of the durable subscriber `noLocal` - if `true`, allows subscriber to inhibit delivery of messages published by its own connection `xact` - if `true`, session will be transacted `clientId` - the client id `selector` - the message selector
`unsubscribe` operation on all JMSDestinationResource MBeans whose domain = `topic` | `unsubscribe` | Removes the durable subscription. The operation takes the following arguments: `name` - name of the durable subscriber `xact` - if `true`, session will be transacted `clientId` - the client id
`browse` operation on all JMSDestinationResource Mbeans | `browse` | Browse this destination. The operation takes the following arguments: `sub` - name of the durable subscriber, only available for MBeans where domain = `topic` `xact` - if `true`, session will be transacted `clientId` - the client ID (optional) `selector` - the message selector (optional) `count` - the maximum number of messages to process (`0` for all)
`copy` operation on all JMSDestinationResource Mbeans | `copy` | Copies messages from this destination to the specified destination. The operation takes the following arguments: `sub` - name of the durable subscriber, only available for MBeans where domain = `topic` `toDestination` - the destination to move the messages to `xact` - if `true`, session will be transacted `clientID` - the client ID (optional) `selector` - the message selector (optional) `count` - the maximum number of messages to process (`0` for all)
`drain` operation on all JMSDestinationResource Mbeans | `drain` | Drain messages from this destination. The operation takes the following arguments: `sub` - name of the durable subscriber, only available for MBeans where domain = `topic` `xact` - if `true`, session will be transacted `clientId` - the client ID (optional) `selector` - the message selector (optional) `count` - the maximum number of messages to process (`0` for all)
`move` operation on all JMSDestinationResource Mbeans | `move` | Moves messages from this destination to the specified destination. The operation takes the following arguments: `sub` - name of the durable subscriber, only available for MBeans where domain = `topic` `toDestination` - the destination to move the messages to `xact` - if `true`, session will be transacted `clientID` - the client ID (optional) `selector` - the message selector (optional) `count` - the maximum number of messages to process (`0` for all)

#### 3.3.2.8 Configuring File-Based Persistence

The following sections discuss file-based persistence:

- Enabling File-Based Persistence in the Application Server Control Console

- Enabling File-Based Persistence in the jms.xml File

- Persistence Recovery

When file-based persistence is enabled OC4J automatically performs the following:

- If a persistence file does not exist, then OC4J automatically creates the file and initializes it with the appropriate data.

- If the persistence file exists and is empty, then OC4J initializes it with the appropriate data.

Caution: A persistence file must not be copied, deleted, or renamed when the OC4J server is active. Doing so can result in data corruption and message loss. If OC4J is not active, then deleting a persistence file is equivalent to deleting all messages and durable subscriptions in the destination associated with that persistence file. When OC4J starts up again, the JMS server re initializes the file as usual. For more information on this, see "Persistence File Management".

Even if persistence is enabled, only certain messages are persisted to a file. For a message to be persisted, all of the following conditions must be true:

- The destination object is defined to be persistent by specifying a persistence file in the Application Server Control Console or by setting the destination's `persistence-file` attribute in the `jms.xml` file.

- The message has a `PERSISTENT` delivery mode, which is the default.

  Messages sent to persistent destinations that are defined with a non-persistent delivery mode (defined as `DeliveryMode.NON_PERSISTENT`) are not persisted.

- The destination is a queue, or the destination is a topic and the consumer is a durable subscriber.

Setting the `DeliveryMode` to `PERSISTENT` or `NON_PERSISTENT` is described in the JMS specification.

Setting the default `DeliveryMode` for a message producer is described at: `http://java.sun.com/j2ee/1.4/docs/api/javax/jms/MessageProducer.html#setDeliveryMode(int)`

Setting a per-message `DeliveryMode` (over-riding the default) is described at: `http://java.sun.com/j2ee/1.4/docs/api/javax/jms/MessageProducer.html#send(javax.jms.Destination,%20javax.jms.Message,%20int,%20int,%20long)`

and at: `http://java.sun.com/j2ee/1.4/docs/api/javax/jms/MessageProducer.html#send(javax.jms.Message,%20int,%20int,%20long)`

Notes on Enabling File-Based Persistence

Given that the previously-listed conditions are met, the file-based persistence option features recoverable and persistent storage of messages. Each destination can be associated with a relative or absolute path name that points to a file that stores the messages sent to the destination object. The file can reside anywhere in the file system (and not necessarily inside a `J2EE_HOME` directory). Multiple persistence files can be placed in the same directory. Persistence files can be placed on a remote network file system or can be part of a local file system.

##### 3.3.2.8.1 Enabling File-Based Persistence in the Application Server Control Console

The Application Server Control Console is the primary tool for enabling file-based persistence for destination objects. Use the following path to specify the parameters of the persistence file in the Application Server Control Console.

Path to specify persistence files for destinations in the Application Server Control Console:

OC4J:Home > Administration tab > Task Name: Services, JMS Providers:, Go To Task > Destinations > Create New > "Persistence File"

You can specify a persistence file in the Application Server Control Console when creating a new destination. You cannot modify the persistence file specification for an existing destination in the Console. You can modify the persistence specification in the `jms.xml` file. See Enabling File-Based Persistence in the jms.xml File.

##### 3.3.2.8.2 Enabling File-Based Persistence in the jms.xml File

You can enable file-based persistence for destination objects, by specifying the `persistence-file` attribute in the `jms.xml` file.

The following XML configuration example demonstrates how the `persistence-file` attribute defines the name of the file as `pers`.

    <queue name="foo" location="jms/persist" persistence-file="pers">
    </queue>

The path for the `persistence-file` attribute is either an absolute path of the file or a path relative to the persistence directory defined in `application.xml`.

The OC4J server will not create any directories for persistence files. So when a persistence file is defined in `jms.xml` it must either be in an existing absolute directory, for example:

     persistence-file="/this/dir/exists/PersistenceFile"

or simply be a filename for example:

    persistence-file="PersistenceFile"

In the latter case, by default the persistence file will be created in `$J2EE_HOME/persistence` (for a standalone instance) or `$J2EE_HOME/persistence/<group_name>` (in the full Oracle Application Server environment).

The `persistence-file` attribute is discussed in Table 3-2, "Configuration Elements".

Oracle Application Server may have multiple OC4J instances writing to the same file directory, even with the same persistence filename. Setting this attribute enables file-based persistence, but also creates the possibility that your persistence files can be overwritten by another OC4J instance.

##### 3.3.2.8.3 Persistence Recovery

The following sections discuss the various aspects of persistence recovery:

- Scope of Recoverability

- Persistence File Management

- Reporting Errors to the JMS Client

- Recovery Steps

Scope of Recoverability

The OEMS JMS File-Based persistence option can recover from some but not all possible failures. If any of the following failures occurs, then recoverability of the persistence file is not guaranteed:

- Media corruption - The disk system holding the persistence file fails abnormally or gets corrupted.

- External corruption - The persistence file is deleted, edited, modified, or otherwise corrupted (by software). Only the JMS server should write into a persistence file.

- Silent failure or corruption - The I/O methods in the JDK fail silently or corrupt data that are being read or written silently.

- A `java.io.FileDescriptor.sync()` failure - The `sync()` call does not properly and completely flush all file buffers associated with the given descriptor to the underlying file system.

Persistence File Management

When the JMS server is running, you must not copy, delete, or rename persistence files currently in use. It is an unrecoverable error to perform any of these actions on any of the persistence files when they are being used.

However, when no OEMS server is using a persistence file, you can perform the following administrative and maintenance operations on the persistence files:

- delete - Deleting a persistence file removes all messages and, in the case of topics, all durable subscriptions. On startup, OEMS JMS initializes a new (and empty) persistence file.

- copy - An existing persistence file can be copied for archival or backup purposes. If an existing persistence file becomes corrupted, an earlier version can be used (as long as the association between the OEMS JMS destination name and the file is maintained), pointed to by any suitable path name, to go back to the previous contents of the JMS destination.

Persistence files cannot be concatenated, split up, rearranged, or merged. Attempting any of these operations causes unrecoverable corruption of the data in these files.

In addition to persistence files specified by a user and lock files, the OEMS JMS In-Memory and File-Based options use a special file, `jms.state`, for internal configuration and transaction state management. The OEMS JMS server cleans up this file and its contents during normal operations. You must never delete, move, copy, or otherwise modify this file, even for archival purposes. Attempting to manipulate the `jms.state` file can lead to message and transaction loss.

Note: The location of the `jms.state` file is different depending on whether you are operating OC4J in standalone or in Oracle Application Server mode, as follows: Standalone: `J2EE_HOME``/persistence` directory Oracle Application Server: `J2EE_HOME``/persistence/<group_name>` directory The location of the persistence directory is defined in the `application.xml` file.

Reporting Errors to the JMS Client

The sequence of operations when a JMS client enqueues or dequeues a message, or commits or rolls back a transaction, is as follows:

1. Client makes a function call

2. Pre-persistence operations

3. Persistence occurs

4. Post-persistence operations

5. Client function call returns

If a failure occurs during the pre-persistence or persistence phase, then the client receives a `JMSException` or some other type of error, but no changes are made to the persistence file.

If a failure occurs in the post-persistence phase, the client may receive a `JMSException` or some other type of error; however, the persistence file is still updated, and OEMS JMS recovers as if the operation succeeded.

#### 3.3.2.9 Abnormal Termination

If OC4J terminates normally, then the lock files are cleaned up automatically. However, if OC4J terminates abnormally, for example, a `kill -9` command, then the lock files remain in the file system. OC4J can usually recognize leftover lock files. If not, you must manually remove lock files before restarting OC4J after abnormal termination.

The default location of the lock files is in the persistence directory—`J2EE_HOME``/persistence`. The persistence directory is defined in the `application.xml` file. Other locations can be set within the `persistence-file` attribute of the destination object.

##### 3.3.2.9.1 Recovery Steps

Lock files prevent multiple OC4J processes from writing into the same persistence file. If multiple OC4J JVMs are configured to point to the same persistence file in the same location, then they could overwrite each other's data and cause corruption or loss of persisted JMS messages. To protect against such sharing violations, OEMS JMS associates each persistence file with a lock file. Thus, each persistence file—for example, `/path/to/persistenceFile`— is associated with a lock file named `/path/to/persistenceFile.lock`. See "Configuring File-Based Persistence" for more information on persistence files.

OC4J must have appropriate permissions to create and delete the lock file.

On termination and restart, one of the following lock-file scenarios will apply:

- Normal termination - Lock files are automatically cleaned up. Restart proceeds normally.

- Abnormal termination - On restart, lock files are recognized. Restart proceeds normally.

- Abnormal termination - On restart, a CRITICAL message is delivered indicating a sharing violation. Restart cannot continue. Delete the lock file indicated in the error message and restart. If more than one lock file is involved, you may have to do this once for each.

JMS persistence lock files are tagged with (contain) server and persistence directory location info. If the lock file exists when the JMS server starts, and the lock file was created by the same server (having the same ip address) and using the same persistence directory location, then the JMS server will assume control of the lock file and start up successfully.

The remainder of this discussion of OEMS JMS File-Based recovery steps in this subsection assumes that all lock files in question have been removed.

OEMS JMS performs recovery operations on all persistence files as configured in OEMS JMS at the time of abnormal termination. In other words, if OC4J terminates abnormally and then the user modifies the JMS server configuration and restarts OC4J, the JMS server still attempts to recover all the persistence files in the original configuration, and, after recovery is successful, moves to using the new configuration specified.

If recovery of the old configuration fails, then the JMS server does not start. The server must be shut down or restarted repeatedly to give recovery another chance, until recovery is successful.

The JMS server caches its current persistence configuration in the `jms.state` file, which is also used to maintain transaction state. If you wish to bypass all recovery of the current configuration, you can remove the `jms.state` file, remove all lock files, possibly change the configuration, and start the server in a clean-slate mode. (Oracle does not recommend doing this.) If the JMS server cannot find a `jms.state` file, then it creates a new one.

If, for some reason, the `jms.state` file itself is corrupted, then the only recourse is to delete it, with the attendant loss of all pending transactions—that is, transactions that have been committed, but the commits not yet performed by all individual destination objects participating in the transactions.

If messaging activity was in progress during abnormal termination, then OEMS JMS tries to recover its persistence files. Any data corruption (of the types mentioned earlier) is handled by clearing out the corrupted data; this may lead to a loss of messages and transactions.

If the headers of a persistence file are corrupted, OEMS JMS may not be able to recover the file, because such a corrupted file is often indistinguishable from user configuration errors. The `oc4j.jms.forceRecovery` administration property (described in Table 3-4, "System Properties") instructs the JMS server to proceed with recovery, clearing out all invalid data at the cost of losing messages or masking user configuration errors.

#### 3.3.2.10 Predefined Exception Queue

As an extension to the JMS specification, OEMS JMS In-Memory and File-Based options come with a predefined exception queue for handling undeliverable messages. This is a single, persistent, global exception queue to store undeliverable messages in originating in any OEMS JMS destination. The exception queue has the following fixed properties:

- A fixed name - `jms/Oc4jJmsExceptionQueue`

- A fixed JNDI location - `jms/Oc4jJmsExceptionQueue`

- A fixed persistence file - `Oc4jJmsExceptionQueue`

Note: The location of the `Oc4jJmsExceptionQueue` persistence file varies according to whether you are operating OC4J in standalone or Oracle Application Server mode, as follows: Standalone directory: `J2EE_HOME/persistence` Oracle Application Server directory: `J2EE_HOME/persistence/<group_name>` The location of the `persistence` directory is defined in the `application.xml` file.

The exception queue is always available to the JMS server and its clients, and should not be explicitly defined in the `jms.xml` configuration file. Attempting to do so is an error. The name, JNDI location, and persistence path name of the exception queue are reserved words in their respective name spaces. Any attempt to define other entities with these names is an error.

Messages can become undeliverable because of message expiration and listener errors. The following subsection explains what happens to undeliverable messages in case of message expiration.

##### 3.3.2.10.1 Message Expiration

By default, if a message sent to a persistent destination expires, then it is moved to the exception queue. The `JMSXState` of the expiring message is set to the value `3` (indicating `EXPIRED`), but the message headers, properties, and body are not otherwise modified. The message is wrapped in an `ObjectMessage` and the wrapping message is sent to the exception queue.

The wrapping `ObjectMessage` has the same `DeliveryMode` as the original message.

By default, messages expiring on non persistent or temporary destination objects are not moved to the exception queue. Normally, the messages sent to these destination objects are considered not worth persisting and neither are their expired versions.

You can specify that all expired messages be sent to the exception queue, regardless of whether they are sent to persistent, non persistent, or temporary destination objects, by setting the `oc4j.jms.saveAllExpired` administration property, described in Table 3-4, "System Properties", to `true` when starting the OC4J server. In this case, all expired messages are moved to the exception queue. Even though this causes non persistent messages to be sent to the exception queue, it does not change their non persistent nature.

#### 3.3.2.11 Message Paging

The OEMS JMS In-Memory and File-Based options support paging in and out message bodies under the following circumstances:

- The message has a persistent delivery mode.

- The message is sent to a persistent destination object (see "Configuring File-Based Persistence").

- The destination is a queue, or the destination is a topic and the consumer is a durable subscriber.

- The amount of used memory in the OC4J server's JVM is above some user-defined threshold.

Only message bodies are paged. Message headers and properties are never paged. You can set the paging threshold through the system property, `oc4j.jms.pagingThreshold`, described in Table 3-4, "System Properties".

The value ranges from somewhere above `0.0` to somewhere below `1.0`. It is almost impossible to write a Java program that uses no JVM memory, and programs almost always die by running out of memory before the JVM heap gets full.

For example, if the paging threshold is `0.5`, and the memory usage fraction of the JVM rises to `0.6`, the JMS server tries to page out as many message bodies as possible until the memory usage fraction reduces below the threshold, or no more message bodies can be paged out.

When a message that has been paged out is requested by a JMS client, the JMS server automatically pages in the message body (regardless of the memory usage in the JVM) and delivers the correct message header and body to the client. After the message has been delivered to the client, it may once again be considered for paging out, depending on the memory usage in the server JVM.

If the memory usage fraction drops below the paging threshold, then the JMS server stops paging out message bodies. The bodies of messages already paged out are not automatically paged back in. The paging in of message bodies happens only on demand (that is, when a message is dequeued or browsed by a client).

By default, the paging threshold is set to `1.0`. In other words, by default, message bodies are never paged.

The user should choose a suitable value for the paging threshold depending on the JMS applications, the sizes of the messages they send and receive, and the results of experiments and memory usage monitoring on real-life usage scenarios.

No value of the paging threshold is ever incorrect. JMS semantics are always preserved regardless of whether paging is enabled or disabled. Control of the paging threshold does allow the JMS server to handle more messages in memory than it might have been able to without paging.

#### 3.3.2.12 JMS Configuration Properties

Runtime configuration of the OEMS JMS In-Memory and File-Based options and JMS clients is accomplished through JVM system properties. None of these properties affect basic JMS functionality. They pertain to features, extensions, and performance optimizations that are specific to the JMS server. These are the properties that you see when you use the knobs command line command.

The primary tool for editing configuration properties at runtime is the `JMSAdministrator` MBean.

As a secondary method, in standalone, you can pass the configuration properties in as a command line argument as follows:

    java -D<propertyname>=<value>

These property settings are persisted in the `jms.xml` file.

Path to JMS configuration properties settings in the JMSAdministratorResource MBean:

OC4J:Home > Administration tab > Task Name: JMX.System MBean Browser > Go To Task > Drill down: J2EEDomain:oc4j, J2EEServer:standalone, JMSAdministratorResource, "JMSAdministrator" > Operations tab > setConfigProperty

Table 3-4 lists and describes the system properties for the OEMS JMS resource provider In-Memory and File-Based options.

Table 3-4 System Properties

JVM System Property | Server/ Client | Description
--- | --- | ---
`oc4j.jms.serverPoll` | JMS client | Interval (in milliseconds) that JMS connections ping the OC4J server and report communication exceptions to exception listeners. Type =long. Default = `15000`.
`oc4j.jms.messagePoll` | JMS client | Maximum interval (in milliseconds) that JMS consumers wait before checking for new messages. Type =long. Default = `1000`.
`oc4j.jms.listenerAttempts` | JMS client | Number of listener delivery attempts before the message is declared undeliverable. This property only limits the number of delivery attempts when the message is being received by means of a MessageListener registered with JMS using one of the `setMessageListener()` methods. It does not limit the number of delivery attempts when a message is being received by means of one of the receive methods (except in the case where the message was already declared undeliverable by a previous delivery attempt to a MessageListener). Note that the JMS Connector implements inbound messaging for MDBs using the receive methods, so this property does not apply in that situation. Furthermore, due to J2EE 1.4 restrictions on the use of Message Listeners, this property is only applicable to application clients. For MDBs, the `MaxDeliveryCnt` activation spec property should be used to limit message delivery attempts. The `orion-ejb-jar.xml` demo file contains comments describing the `MaxDeliveryCnt` property. Type =int. Default = `5`.
`oc4j.jms.maxOpenFiles` | OC4J server | Maximum number of open file descriptors for persistence files. This is relevant if the server is configured with more persistent destination objects than the maximum number of open file descriptors allowed by the operating system. Type =int. Default = `64`.
`oc4j.jms.saveAllExpired` | OC4J server | Save all expired messages on all destination objects (persistent, nonpersistent, and temporary) to the exception queue. Type =boolean. Default = `false`.
`oc4j.jms.socketBufsize` | JMS client | When using TCP/IP sockets for client-server communication, use the specified buffer size for the socket input/output streams. A minimum buffer size of 8 KB is enforced. The larger the size of messages being transferred between the client and server, the larger the buffer size should be to provide reasonable performance. Type =int. Default = `64*1024`.
`oc4j.jms.debug` | JMS client | If `true`, enable tracing of `NORMAL` events in JMS clients and the JMS server. All log events (`NORMAL`, `WARNING`, `ERROR`, and `CRITICAL`) are sent to both `stderr` and, when possible, either `J2EE_HOME``/log/server.log` or `J2EE_HOME``/log/jms.log`. Setting this property to `true` typically generates large amounts of tracing information. Type =boolean. Default = `false`.
`oc4j.jms.noDms` | JMS client | If `true`, disable instrumentation. Type =boolean. Default = `false`.
`oc4j.jms.forceRecovery` | OC4J server | If `true`, forcibly recover corrupted persistence files. By default, the JMS server does not perform recovery of a persistence file if its header is corrupted (because this condition is, in general, indistinguishable from configuration errors). Forcible recovery allows the JMS server almost always to start up correctly and make persistence files and destination objects available for use. Type =boolean. Default = `false`.
`oc4j.jms.pagingThreshold` | OC4J server | Represents the memory usage fraction above which the JMS server begins to consider message bodies for paging. This value is an estimate of the fraction of memory in use by the JVM. This value can range from `0.0` (the program uses no memory at all) to `1.0` (the program is using all available memory). Type =double. Default = `1.0`. See "Message Paging" for more information.

Setting JMS Configuration Properties in the jms.xml File

The following fragment shows how a configuration property is set in the `jms.xml` file.

        <config-properties>
          <config-property name="oc4j.jms.debug" value="true">
          </config-property>
        </config-properties>

This fragment is shown in context in the `jms.xml` example at "Configuration Using jms.xml". It is also covered in Table 3-2, "Configuration Elements".

#### 3.3.2.13 Resource Naming for OEMS JMS In-Memory and File-Based

The variable resourceName is used in this section to represent the JNDI location of an RP resource (connection factory or destination) within the resource provider's JNDI context.

The resourceName of an OEMS JMS resource is specified as a JNDI location in the console as described in Configuring Destination Objects and Connection Factories. Connection factory resourceName values are used to identify a specific OEMS JMS connection factory (as the link-key for arrow #16 in Figure 3-1). Destination resourceName values are used to identify a specific OEMS JMS destination (as the link-key for arrow #13 in Figure 3-1). Connection factory and destination resourceName values may also be used when bypassing the JMS Connector as discussed in Bypassing the JMS Connector for Application Clients.

#### 3.3.2.14 Required Class Path for Application Clients Using Direct OEMS JMS In-Memory and File-Based Lookup

When using OEMS JMS In-Memory and File-Based options directly from an application client, the JAR files that must be included in the class path are listed inTable 3-5, "Client-side JAR Files Required for OEMS JMS In-Memory and File-Based Lookup".

Note: For 10g Release 3 (10.1.3), OEMS JMS cannot be used for global transactions without the JMS Connector.

Table 3-5 Client-side JAR Files Required for OEMS JMS In-Memory and File-Based Lookup

JAR | ORACLE_HOME Path
--- | ---
`oc4jclient.jar` | `/j2ee/<instance>`
`jta.jar` | `/j2ee/<instance>/lib`
`jms.jar` | `/j2ee/<instance>/lib`
`jndi.jar` | `/j2ee/<instance>/lib`
`javax77.jar` | `/j2ee/<instance>/lib`
`optic.jar` (Required only if the `opmn:ormi` prefix is used in Oracle Application Server environment.) | `/opmn/lib`

### 3.3.3 OEMS JMS Database Persistence

The OEMS JMS Database persistence option is the JMS interface to the Oracle Database Streams Advanced Queuing (AQ) feature in the Oracle database. This section will cover in detail the configuration and usage of OEMS JMS using AQ as the persistent store for messages.

As with the OEMS JMS In-Memory and File-Based options, Oracle recommends that your applications use the JMS Connector when accessing AQ through the OEMS JMS Database option.

For details about configuring OEMS JMS with AQ, see the Oracle Streams Advanced Queuing User's Guide and Reference.

This section describes the following topics:

- Using the OEMS JMS Database Option

- Using OEMS JMS Database with the Oracle Application Server and the Oracle Database

Note: In past Oracle Application Server documentation and collateral, as well as in the Oracle Streams Advanced Queuing User's Guide and Reference, you will see the OEMS JMS Database persistence option described as "OJMS". When you encounter the acronym, "OJMS", it is describing the OEMS JMS Database persistence option.

#### 3.3.3.1 Using the OEMS JMS Database Option

To create and access OEMS JMS Database resource provider destination objects (queues and topics), do the following:

- Install and configure OEMS JMS on the database. See "Install and Configure OEMS JMS Database".

- On the database, create an RDBMS user. The JMS application will connect the RDBMS user to the back-end database and assign privileges. See "Create User and Assign Privileges".

- Create the JMS destination objects. See "Creating OEMS JMS Database Destination Objects".

- Create data sources or LDAP directory entries, if needed. See "Declaring the OEMS JMS Database Reference".

- In the OC4J XML configuration, define the OEMS JMS Database option in the `<resource-provider>` element of the `orion-application.xml` file with information about the back-end database.

- Access the resource in your implementation through a JNDI lookup. See "Sending and Receiving JMS Messages".

##### 3.3.3.1.1 Install and Configure OEMS JMS Database

You or your DBA must install OEMS JMS according to the Oracle Streams Advanced Queuing User's Guide and Reference and generic database manuals. After you have installed and configured OEMS JMS, you must apply additional configuration. This includes the following:

1. You or your DBA must create an RDBMS user through which the JMS client connects to the database. Grant this user appropriate access privileges to perform OEMS JMS operations. OEMS JMS allows any database user to access queues in any schema, provided that the user has the appropriate access privileges. See "Create User and Assign Privileges".

2. You or your DBA must create the tables and queues to support the JMS destination objects. See "Creating OEMS JMS Database Destination Objects".

   Note: The following sections use SQL for creating queues, topics, and their tables, and for assigning privileges. For examples, see `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`.

##### 3.3.3.1.2 Create User and Assign Privileges

Create an RDBMS user through which the JMS client connects to the database. Grant access privileges to this user to perform OEMS JMS operations. The privileges that you need depend on what functionality you are requesting. Refer to the Oracle Streams Advanced Queuing User's Guide and Reference for more information on privileges necessary for each type of function.

The following example creates `jmsuser`, which must be created within its own schema, with privileges required for OEMS JMS operations. You must be a `SYS` `DBA` to execute these statements.

    DROP USER jmsuser CASCADE ;

    GRANT connect,resource,AQ_ADMINISTRATOR_ROLE TO jmsuser
       IDENTIFIED BY jmsuser ;
    GRANT execute ON sys.dbms_aqadm  TO  jmsuser;
    GRANT execute ON sys.dbms_aq     TO  jmsuser;
    GRANT execute ON sys.dbms_aqin   TO  jmsuser;
    GRANT execute ON sys.dbms_aqjms  TO  jmsuser;

    connect jmsuser/jmsuser;

You may need to grant other privileges, such as two-phase commit or system administration privileges, based on what the user needs. See Chapter 5, "OC4J Transaction Support", for information on two-phase commit privileges.

##### 3.3.3.1.3 Creating OEMS JMS Database Destination Objects

Refer to the Oracle Streams Advanced Queuing User's Guide and Reference for information on the `DBMS_AQADM` packages and OEMS JMS Database messages types.

Note: For examples, see `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`.

The following examples demonstrate creating a queue and a topic in OEMS JMS Database.

1. Create the table that handles the OEMS JMS destination (queue or topic).

   Both topics and queues use a queue table. The following SQL example creates a single table, `demoTestQTab,` for a queue.

       DBMS_AQADM.CREATE_QUEUE_TABLE(
               Queue_table            => 'demoTestQTab',
               Queue_payload_type     => 'SYS.AQ$_JMS_MESSAGE',
               sort_list => 'PRIORITY,ENQ_TIME',
               multiple_consumers  => false,
               compatible             => '8.1.5');

   The `multiple_consumers` parameter specifies whether there are multiple consumers. Set `multiple_consumers` to `false` for a queue. Set `multiple_consumers` to `true` for a topic.

2. Create the JMS destination. This SQL example creates a queue called `demoQueue` within the queue table `demoTestQTab` and then starts the queue.

       DBMS_AQADM.CREATE_QUEUE(
             Queue_name          => 'demoQueue',
             Queue_table         => 'demoTestQTab');

       DBMS_AQADM.START_QUEUE(
             queue_name         => 'demoQueue');

Example:

The following example shows how you can create a topic called `demoTopic` within the topic table `demoTestTTab`. After creation, two durable subscribers are added to the topic. Finally, the topic is started.

Note: OEMS JMS Database uses the `DBMS_AQADM.CREATE_QUEUE` method to create both queues and topics.

    DBMS_AQADM.CREATE_QUEUE_TABLE(
            Queue_table            => 'demoTestTTab',
            Queue_payload_type     => 'SYS.AQ$_JMS_MESSAGE',
            multiple_consumers  => true,
            compatible             => '8.1.5');
    DBMS_AQADM.CREATE_QUEUE( 'demoTopic', 'demoTestTTab');
    DBMS_AQADM.START_QUEUE('demoTopic');

Note: OEMS JMS Database incorporates the (`Queue_name`) names passed into the `DBMS_AQADM.CREATE_QUEUE` method into the JNDI names for the destinations. For example, OEMS JMS Database makes the queue created with `Queue_name` "`demoQueue`" available with the JNDI name "`Queues/demoQueue`". In order to wrap an OEMS JMS destination with a JMS Connector destination, the OEMS JMS-provided JNDI name for the destination and the "`jndiName`" `<config-property>` for the JMS Connector destination defined in the `oc4j-connectors.xml` file (either the global one in `$J2EE_HOME/config` or a local one optionally contained in an application's .ear file) must match. See arrow #13 in Figure 3-1, "JMS Infrastructure"

##### 3.3.3.1.4 Declaring the OEMS JMS Database Reference

For an overview of declaring the resource provider reference, see "Declaring Resource Provider References".

The two pieces of information you must provide whenever declaring a resource provider reference are the name you wish to use for the resource provider reference and the Java class that implements the resource provider interface.

For OEMS JMS Database, the class is `oracle.jms.OjmsContext`. To declare a resource provider reference named `OJMSReference`, use:

        <resource-provider class="oracle.jms.OjmsContext" name="OJMSReference">    ...    </resource-provider>

For example, if the OEMS JMS reference is named `OJMSReference`, and the JNDI location (within the resource provider's JNDI context of a resource provider queue is `Queues/MY_QUEUE`, then that resource provider queue is accessible to the application and resource adapter at JNDI location `java:comp/resource/OJMSReference/Queues/MY_QUEUE`.

In general, use the following steps to declare an OEMS JMS reference:

1. First create a local data-source in the `data-sources.xml` file. The demo set has an example of this at: `/ojms/src/META-INF/data-sources.xml`.

2. Then tell OC4J where the `data-sources.xml` file has been placed by adding a `<data-sources>` element to `orion-application.xml`:

           <data-sources path="data-sources.xml"/>

   Note that the data-sources path is relative to the `orion-application.xml` file.

3. Finally, set the datasource for the resource provider reference by adding a `<property>` subelement to the previously created `<resource-provider>` element:

           <resource-provider class="oracle.jms.OjmsContext" name="OJMSReference">
               <property name="datasource" value="jdbc/xa/MyChannelDemoDataSource"></property>
           </resource-provider>

   Configuring data sources is discussed in the "Data Sources" chapter of this guide. When selecting which driver to use (OCI or thin), it is best to measure actual application performance. The OCI driver may be faster for non-XA operations, but can be significantly slower than the thin driver for XA operations.

For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

##### 3.3.3.1.5 Resource Naming for OEMS JMS Database

The resourceName of an OEMS JMS Database resource is:

typeName/instanceName

The values for typeName and instanceName depend on the type of resource (connection factory or destination), and are described next.

For OEMS JMS Database connection factories:

typeName corresponds to the connection factory type and is one of the following:

- `ConnectionFactories`

- `QueueConnectionFactories`

- `TopicConnectionFactories`

- `XAConnectionFactories`

- `XAQueueConnectionFactories`

- `XATopicConnectionFactories`

instanceName can be anything (because it is ignored - OEMS JMS Database connection factories are not customizable so there is no need for multiple instances of the same connection factory type).

For example, the resourceName for an OEMS JMS Database non-XA queue connection factory (where the ignored instanceName is arbitrarily set to `myQCF`) is:

     QueueConnectionFactories/myQCF

Connection factory resourceName values created as per the above instructions are used to identify a specific OEMS JMS Database connection factory (that is, as the link-key for arrow #16 in Figure 3-1, "JMS Infrastructure"). They may also be used when bypassing the resource adapter as discussed in Bypassing the JMS Connector for Application Clients.

The following table shows the `javax.jms.*` interfaces implemented.

Table 3-6 javax.jms.* Interfaces Implemented

typeName | CF | QCF | TCF | XACF | XAQCF | XATCF
--- | --- | --- | --- | --- | --- | ---
ConnectionFactories | X |  |  |  |  |
QueueConnectionFactories | X | X |  |  |  |
TopicConnectionFactories | X |  | X |  |  |
XAConnectionFactories | X |  |  | X |  |
XAQueueConnectionFactories | X | X |  | X | X |
XATopicConnectionFactories | X |  | X | X |  | X

If the application requires a `javax.jms.TopicConnectionFactory` (as specified by the `<res-type>` element), the only type names that will return a suitable connection factory are`"TopicConnectionFactories"` and `"XATopicConnectionFactories"`.

For OEMS JMS Database destinations:

typeName corresponds to the destination type and is one of the following:

- `Queues`

- `Topics`

Note: A destination is a queue (typeName = `Queues`) if the `multiple_consumers` parameter passed to `DBMS_AQADM.CREATE_QUEUE_TABLE` was `false`. Otherwise the destination is a topic (typeName = `Topics`).

instanceName is the name of the destination (the Queue_Name parameter provided to `DBMS_AQADM.CREATE_QUEUE`). If the destination is not owned by the user specified in the `username` property in the `<resource-provider>` element, then instanceName must be prefixed with "owner." where owner is the owner of the destination. (Even when not required, the "owner." prefix is still allowed.)

For example, the resourceName for an OEMS JMS Database queue given the name `demoQueue` in the call to `DBMS_AQADM.CREATE_QUEUE` is:

    Queues/demoQueue

If the owner (for example, `someUser`) needs to be specified, then the resourceName would be:

     Queues/someUser.demoQueue

Destination resourceName values created according to the above instructions are used to identify a specific OEMS JMS Database destination (that is, as the link-key for arrow #13 in Figure 3-1). They may also be used when bypassing the resource adapter as discussed in Bypassing the JMS Connector for Application Clients.

##### 3.3.3.1.6 Sending and Receiving Messages Using OEMS JMS Database Persistence

Oracle recommends that the application use the JMS Connector for sending and receiving messages. In this way the sending and receiving code can be independent of the resource provider used. The examples at "Sending and Receiving JMS Messages" can be used for all resource providers, including OEMS JMS Database, with only the passed-in destination and connection factory locations being different.

##### 3.3.3.1.7 Required Class Path for Application Clients Using Direct OEMS JMS Database Lookup

When using OEMS JMS Database options directly from an application client, the JAR files that must be included in the class path are listed inTable 3-7, "Client-side JAR Files Required for OEMS JMS Database Lookup".

Table 3-7 Client-side JAR Files Required for OEMS JMS Database Lookup

JAR | ORACLE_HOME Path
--- | ---
`oc4jclient.jar` | `/j2ee/<instance>`
`ejb.jar` | `/j2ee/<instance>/lib`
`jta.jar` | `/j2ee/<instance>/lib`
`jms.jar` | `/j2ee/<instance>/lib`
`jndi.jar` | `/j2ee/<instance>/lib`
`javax77.jar` | `/j2ee/<instance>/lib`
`adminclient.jar` | `/j2ee/<instance>/lib`
`ojdbc14dms.jar` | `/j2ee/<instance>/../../oracle/jdbc/lib`
`dms.jar` | `/j2ee/<instance>/../../oracle/lib`
`bcel.jar` | `/j2ee/<instance>/lib`
`optic.jar` (Required only if the `opmn:ormi` prefix is used in Oracle Application Server environment.) | `/opmn/lib`

#### 3.3.3.2 Using OEMS JMS Database with the Oracle Application Server and the Oracle Database

This section discusses common issues encountered by users of OEMS JMS Database with Oracle Application Server.

- Error When Copying aqapi.jar

- OEMS JMS Database Certification Matrix

##### 3.3.3.2.1 Error When Copying aqapi.jar

A common error seen when using the OEMS JMS Database option with the Oracle Application Server is:

    PLS-00306 "wrong number or types of arguments"

If you receive this message, then the `aqapi.jar` file being used in Oracle Application Server is not compatible with the version of the Oracle database being used for AQ. A common mistake is to copy the `aqapi.jar` file from the Oracle database installation into the Oracle Application Server installation, or from the Oracle Application Server installation into the Oracle database installation, under the false assumption that they are interchangeable. The confusion is because the Oracle Application Server and the Oracle database both ship the OEMS JMS client JAR file. Do not copy this file. Use the matrix in Table 3-8 to find the correct version of the database and Oracle Application Server, then use the `aqapi.jar` file that comes with the Oracle Application Server.

In an Oracle Application Server installation, the OEMS JMS Database client JAR file can be found at `ORACLE_HOME``/rdbms/jlib/aqapi.jar` and should be included in the `CLASSPATH`.

##### 3.3.3.2.2 OEMS JMS Database Certification Matrix

Table 3-8 indicates which versions of the Oracle database work with the Oracle Application Server when the OEMS JMS client is running in OC4J. An X indicates that the Oracle Database version and the Oracle Application Server version that intersect at that cell are certified to work together. If the cell has no X, then the corresponding version of the Oracle Database and Oracle Application Server should not be used together.

Note: This is not a certification matrix for the Oracle Application Server and the Oracle Database in general. It is only for the OEMS JMS Database persistence option when used in the Oracle Application Server.

Table 3-8 OEMS JMS Database Certification Matrix

OracleAS / Oracle Database | v9.0.1 | v9.0.1.3 | v9.0.1.4 | v9.2.0.1 | v9.2.0.2+ | v10.1.0+
--- | --- | --- | --- | --- | --- | ---
9.0.2 | X | X |  | X |  |
9.0.3 |  |  | X |  |  | X
9.04 |  |  | X |  | X |
9.0.4.1 |  |  |  |  |  | X
10.1.2 |  |  | X |  | X | X
10.1.3 |  |  | X |  |  |

### 3.3.4 Using Third-Party JMS Providers

This section briefly discusses declaring references to the supported third-party JMS resource providers.

OC4J supports two-phase commit (2pc) for all supported resource providers as long as the resource provider has an XA interface and the JMS Connector and application are configured to use it. All of the supported third party providers have an XA interface.

The versions of each third-party JMS provider that OC4J supports are listed at Using Third-Party JMS Providers.

This section provides information on declaring references for the following third-party JMS providers:

- Declaring an IBM WebSphere MQ Resource Provider Reference

- Declaring a TIBCO Enterprise Message Service Resource Provider Reference

- Declaring a SonicMQ Resource Provider Reference

The context-scanning resource provider class is a generic resource provider class shipped with OCJ for use with third-party message providers.

Note: To declare a resource provider reference, use one or the other of the following files: To make the resource provider reference visible to all applications (global), then use the global `application.xml` file. To make the resource provider reference visible to a single application (local), then use the `orion-application.xml` file specific to the application.

#### 3.3.4.1 Declaring an IBM WebSphere MQ Resource Provider Reference

WebSphere MQ is an IBM messaging provider. WebSphere MQ resources are available under

    java:comp/resource/providerName

where providerName is the name used in the `<resource-provider>` element.

To declare a WebSphere MQ resource provider reference, perform the following steps:

1. Install and configure WebSphere MQ on your system, then verify the installation by running any examples or tools supplied by the vendor. See the documentation supplied with the WebSphere MQ software for instructions.

2. Add WebSphere MQ as a custom resource provider.

   The following example demonstrates using the `<resource-provider>` element in the `orion-application.xml` file to declare a WebSphere MQ resource provider reference.

       <resource-provider
           class="com.evermind.server.deployment.ContextScanningResourceProvider"
           name="MQSeries">
         <description> MQSeries resource provider </description>
         <property
             name="java.naming.factory.initial"
             value="com.sun.jndi.fscontext.RefFSContextFactory">
         </property>
         <property
             name="java.naming.provider.url"
             value="file:/home/developer/services_guide_demo/mqseries/src/bindings">
         </property>
       </resource-provider>

   This example shows how this configuration was accomplished in the demo set. It applies to the demo author's environment only and must be edited to work in any other environment.

3. Add to `J2EE_HOME/applib` any JAR files required by a Websphere MQ JMS client as described in the IBM documentation.

   The section "Resource Provider Task #3: Declare a Resource Provider Reference" in the `how-to-gjra-with-mqseries.html` document in the demo set has more detail.

For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

#### 3.3.4.2 Declaring a TIBCO Enterprise Message Service Resource Provider Reference

TIBCO Enterprise Message Service is a message provider from TIBCO Software. TIBCO resources are available under

    java:comp/resource/providerName

where providerName is the name used in the `<resource-provider>` element.

To declare a TIBCO resource provider reference, perform the following steps:

1. Install and configure TIBCO Enterprise Message Service on your system, then verify the installation by running any examples or tools supplied by the vendor. See the documentation supplied with the TIBCO software for instructions.

2. Add TIBCO as a custom resource provider. The following example demonstrates using the `<resource-provider>` element in the `orion-application.xml` file to declare a TIBCO resource provider reference.

           <resource-provider
              class="com.evermind.server.deployment.ContextScanningResourceProvider"
              name="TibcoJMSReference">
               <property
                   name="java.naming.factory.initial"
                   value="com.tibco.tibjms.naming.TibjmsInitialContextFactory">
               </property>
               <property
                   name="java.naming.provider.url"
                   value="tibjmsnaming://jleinawe-sun:7222">
               </property>
           </resource-provider>

   This example shows how this configuration was accomplished in the demo set. It applies to the demo author's environment only and must be edited to work in any other environment.

3. Add to `J2EE_HOME/applib` any JAR files required by a TIBCO JMS client as described in the TIBCO documentation.

   The section "Resource Provider Task #3: Declare a Resource Provider Reference" in the `how-to-gjra-with-tibco.html` document in the demo set has more detail.

For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

#### 3.3.4.3 Declaring a SonicMQ Resource Provider Reference

SonicMQ is a messaging provider from Sonic Software Corporation. Sonic resources are available under

    java:comp/resource/providerName

where providerName is the name used in the `<resource-provider>` element.

To declare a SonicMQ resource provider reference, perform the following steps:

1. Install and configure SonicMQ on your system, then verify the installation by running any examples or tools supplied by the vendor. See the documentation supplied with the Sonic software for instructions.

2. Add SonicMQ as a custom resource provider. The following example demonstrates using the `<resource-provider>` element in the `orion-application.xml` file to declare a SonicMQ resource provider reference.

           <resource-provider
              class="com.evermind.server.deployment.ContextScanningResourceProvider"
              name="SonicJMSReference">
               <property
                   name="java.naming.factory.initial"
                   value="com.sonicsw.jndi.mfcontext.MFContextFactory">
               </property>
               <property
                   name="java.naming.provider.url"
                   value="tcp://stadd41:2506">
               </property>
               <property
                   name="com.sonicsw.jndi.mfcontext.domain"
                   value="Domain1">
               </property>
           </resource-provider>

   This example shows how this configuration was accomplished in the demo set. It applies to the demo author's environment only and must be edited to work in any other environment.

3. Add to `J2EE_HOME/applib` any JAR files required by a SonicMQ JMS client as described in the Sonic documentation.

   The section "Resource Provider Task #3: Declare a Resource Provider Reference" in the `how-to-gjra-with-sonic.html` document in the demo set has more detail.

For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

## 3.4 JMS Connector

Oracle provides a J2CA 1.5-compliant resource adapter called the JMS Connector that allows OC4J-managed applications to have a unified mechanism to access any JMS provider, regardless of whether their level of J2CA support is at version 1.5. The JMS Connector does not use any Oracle proprietary APIs. Supported JMS implementations include OEMS JMS and third-party products such as IBM Websphere MQ JMS, TIBCO Enterprise for JMS, and SonicMQ JMS.

The JMS Connector is the recommended path for JMS usage in the OC4J 10.1.3 implementation. It is based on the J2CA 1.5 and JMS 1.1 and 1.02b standards and includes minimal customization for OC4J, and none for individual JMS providers. It is intended to seamlessly integrate any standard JMS implementation.

(Note that the JMS Connector does not typically provide optimal access to a particular JMS provider, given that many JMS providers support custom extensions.)

The JMS Connector includes features in the following areas:

- JNDI mapping

- MDB integration (including dynamic adjustment to changing message load)

- Global transaction support (including standards-based support for transaction recovery). Transaction support is discussed in Chapter 5, "OC4J Transaction Support".

- True generic JMS connection pooling

- Deployment convenience (including order independence)

- Lazy resolution of JMS operations (including start order independence, tolerance of dynamic management such as starts and stops of JMS providers, and connection retries in case of provider failure)

- Performance

- JSR-77 statistics

Typically, the JMS Connector is used in situations where the EIS being connected is a JMS resource provider. However, it can also be used in situations where the EIS uses JMS messaging as a means of notifying J2EE application components. In this case, the resource adapter (along with a JMS resource provider) can be used instead of the inbound communication features (if any) of the EIS-specific resource adapter. This two-adapter solution, where the EIS-specific adapter is used for outbound communication and the JMS Connector is used for inbound communication, enables bidirectional communication between the EIS and J2EE applications where it may otherwise not be possible.

For more information on resource adaptors see the Oracle Containers for J2EE Resource Adapter Administrator's Guide. For information on using the Application Server Control Console for JMS Connector settings, see Chapter 2. For information on configuring JMS Connector connection factories, see Chapter 3.

### 3.4.1 Modifying the JMS Connector

The JMS Connector provided with OC4J is configured out-of-the-box to support the OEMS JMS In-Memory and File-Based persistence options. If you need to integrate with the OEMS JMS Database option or one of the supported non-Oracle JMS providers then you must create another configuration for the JMS Connector. Another reason you may want to create another JMS Connector is to support an application-local adapter to connect to the OEMS JMS In-Memory and File-Based options.

For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

Create and configure a new JMS Connector module as follows:

1. Go to the demo set for the resource provider to be connected.

2. Read the How-to document.

3. Copy the following files to be used as templates for your new JMS Connector module:

   - `ra.xml`

   - `oc4j-ra.xml`

   - `oc4j-connectors.xml`

4. Modify the `ra.xml`, the `oc4j-ra.xml`, and the `oc4j-connectors.xml` files according to the instructions at "Configuring the Resource Adapter" in the How-to document.

5. Create a new `.rar` file (You can name it whatever you want.) with the following structure:

   `META-INF/ra.xml`

   `META-INF/oc4j-ra.xml`

6. Place the new `oc4j-connectors.xml` in one of the following locations according to the desired level of visibility:

   - For application-local visibility, place the new `oc4j-connectors.xml` file in the top-level `META-INF/` directory of your application's `.ear` file

     For global visibility, copy the new `<connector>` element(s) into the `$J2EE_HOME/config/oc4j-connectors.xml` file. Make sure the name of your new connector (the `<connector>`'s `name` attribute) does not conflict with the name of other connectors or any other JNDI objects.

7. Prepare deployment as follows:

   - For local visibility, do the following:

     - Place the new `.rar` file in the `.ear` file.

     - Insert a `<connectors>` element that looks like the following into the `META-INF/orion-application.xml` file in the `.ear` file.

           <connectors path="oc4j-connectors.xml"/>

     - Insert a `<module>` element that looks like the following into the `META-INF/application.xml` file in the `.ear` file.

           <module>
               <connector>rarFileName</connector>
           </module>

   - For global visibility, follow the instructions for deploying a connector in the Oracle Containers for J2EE Deployment Guide.

### 3.4.2 Configuring the JMS Connector

The Application Server Control Console is the primary tool for configuring the JMS Connector.

#### 3.4.2.1 JMS Connector Connection Factories and Destinations

The default application defines the following destination objects for the default JMS Connector:

- A queue bound to JNDI location OracleASjms/MyQueue1.

- A topic bound to JNDI location OracleASjms/MyTopic1.

- An automatic destination wrapping JNDI subcontext for queues bound to JNDI location OracleASjms/Queues.

- An automatic destination wrapping JNDI subcontext for topics bound to JNDI location OracleASjms/Topics.

Your applications can use these destinations and automatic destination wrapping JNDI subcontexts without your having to add them in the Console or the `JMSAdministrator` MBean.

The JMS Connector default connection factories are as follows:

| XA | non-XA
--- | --- | ---
Default Queue Connection Factory | `OracleASjms/MyXAQCF` | `OracleASjms/MyQCF`
Default Topic Connection Factory | `OracleASjms/MyXATCF` | `OracleASjms/MyTCF`
Default Unified Connection Factory | `OracleASjms/MyXACF` | `OracleASjms/MyCF`

The default connection factories in the table are explicitly declared in the default `oc4j-ra.xml` file that ships with OC4J).

Creating JMS Connector connection factories and destinations

For information on configuring the JMS Connector connection factories and destinations, including examples of the `oc4j-connectors.xml`, `oc4j-ra.xml`, and `ra.xml` files, go to: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

Download and unzip the relevant how-to-gjra-with-xxx.zip file, where xxx is the name of the resource provider. Search for "Configuring the Resource Adapter" in the relevant How-To document.

For detailed reference information on the JMS Connector XML files, go to "Appendix A, OC4J Resource Adapter Configuration Files" of the Oracle Containers for J2EE Resource Adapter Administrator's Guide.

#### 3.4.2.2 JMS Connector Settings

Table 3-9 lists and describes the JMS Connector configuration settings.

Path to JMS Connector Settings in the Application Server Control Console:

OC4J:Home > Applications tab > View: Standalone Resource Adapters > OracleASjms

Table 3-9 JMS Connector Configuration Settings

Console Settings | XML Persistence File(s) | Description
--- | --- | ---
OC4J:Home > Applications tab > View: Standalone Resource Adapters > OracleASjms > Connection Factories tab > Create button Connection Factory Interface This is the link-reference for arrow #14 in Figure 3-1. | This setting is persisted in the `<connectionfactory-interface>` element of the `oc4j-ra.xml` file. | The Connection Factory Interface setting defines the type of connection factory to be created.
JNDI Location This is the link-key for arrow #5 in Figure 3-1. | This setting is persisted in the `location` attribute of a `<connector-factory>` element of the `oc4j-ra.xml` file. | The JNDI Location setting specifies the JNDI location where the new resource adapter connection factory is to be bound. Enter a valid JNDI location so the application component can locate the connection factory when it needs to connect to the EIS. Note that "JNDI Location" is not the same as "jndiLocation".
Connection Pooling | This setting is persisted in the `<connection-pooling>` element of the `oc4j-ra.xml` file. | Connection pooling allows a set of connections to the EIS to be reused within an application. An application can choose to either create its own exclusive connection pool or use one of the shared connection pools available for this resource adapter. `No Connection Pool` - Select this option to disable connection pooling. `Use Private Connection Pool` - Select this option to create a new connection pool for exclusive use by the selected connection factory. `Use Shared Connection Pool` - Select this option to use a shared connection pool that can be used by multiple connection factories. The `oc4j-ra.xml` file contains OC4J-specific configuration for the JMS Connector. Subelements of `<connector-factory>` include `<connection-pooling>`, to set up connection pooling for the factory, and `<security-config>`, to set up container-managed sign-on. Each connector factory can have configuration for a private connection pool, or can use a shared connection pool that is set up through a `<connection-pool>` subelement of `<oc4j-connector-factories>`.
jndiLocation This is the link-reference for arrow #16 in Figure 3-1. | This setting is persisted in a `<config-property>` subelement of a `<connector-factory>` element of the `oc4j-ra.xml` file. | The `jndiLocation` setting specifies the resource provider connection factory to be wrapped by the resource adapter connection factory that you are creating. Note that "jndiLocation" is not the same as "JNDI Location".
`<none>` | This setting is persisted in a `<config-property>` subelement of a `<connector-factory>` element of the `oc4j-ra.xml` file. | The `clientId` setting specifies what client id should be applied to any newly created resource provider connection created by the JMS Connector connection.
OC4J:Home > Applications tab > View: Standalone Resource Adapters > OracleASjms > Administered Objects tab > Create button Object Class | This setting is persisted in an `<adminobject-class>` subelement of an `<adminobject-config>` element of the `oc4j-connectors.xml` file. | The `Object Class` setting defines the type of administered object (destination) to be created. Select from the drop-down list.
JNDI Location This is the link-key for arrows #7 and #11 in Figure 3-1. | This setting is persisted in the `location` attribute of an `<adminobject-config>` element of the `oc4j-connectors.xml` file. | The `JNDI Location` setting specifies the JNDI location where the new resource adapter administered object (destination) is to be bound.
jndiName This is the link-reference for arrow #13 in Figure 3-1. | This setting is persisted in the `value` attribute of a `<config-property>` subelement of a `<adminobject-config>` element of the `oc4j-connectors.xml` file. | The `jndiName` setting is the JNDI name of the resource provider destination to be wrapped by the resource adapter administered object (destination) that you are creating. Note: This description of the `jndiName` setting applies to individually-bound resource provider queues and topics. See the comments in the `oc4j-connectors.xml` files in the demo set for more information.
resourceProviderName This is the link-reference for arrow #12 in Figure 3-1. | This setting is persisted in the `value` attribute of a `<config-property>` subelement of a `<adminobject-config>` element of the `oc4j-connectors.xml` file. | The `resourceProviderName` setting identifies the resource provider that owns the destination to be wrapped by the resource adapter administered object (destination) that you are creating.

For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

#### 3.4.2.3 Configuring the JMS Connector in the XML Files

The JMS Connector configuration settings are persisted in the following files:

- `oc4j-connectors.xml` - The `oc4j-connectors.xml` file is used to create JMS Connector instances and JMS Connector destinations.

- `oc4j-ra.xml` - The `oc4j-ra.xml` file contains OC4J-specific configuration for a JMS Connector. When you use Application Server Control Console to create or edit a JMS Connector connection factory, OC4J updates the `oc4j-ra.xml` file.

- `ra.xml` - The standard JMS Connector module configuration file provided by Oracle. When you configure a JMS Connector, entries in `ra.xml` typically serve as defaults.

For detailed examples of the `oc4j-connectors.xml`, the `oc4j-ra.xml`, and the `ra.xml` files, go to: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

For detailed reference information on the JMS Connector XML files, go to Appendix A, OC4J Resource Adapter Configuration Files of the Oracle Containers for J2EE Resource Adapter Administrator's Guide.

Note: Remember that you must restart the OC4J instance to enable configuration changes made directly in the XML files.

### 3.4.3 Using Message-Driven Beans

OC4J supports Message-Driven Beans (MDBs), using the JMS Connector in OC4J to plug in message providers, including OEMS JMS, as well as the supported third-party message providers. This offers significant advantages such as JMS connection pooling, and MDB listener thread sets that size themselves according to changing load (dynamic load adjustment).

A full example of configuring an MDB is included in the demo at: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

Download and unzip one of the how-to-gjra-with-xxx.zip files, where xxx is the name of the relevant resource provider. MDB example code can be viewed in the following files: `/src/ejb/META-INF/ejb-jar.xml` and `/src/ejb/META-INF/orion-ejb-jar.xml`

Connection Pooling

The JMS Connector uses J2CA connection pooling. For information on connection pooling, see the Oracle Containers for J2EE Resource Adapter Administrator's Guide.

Dynamic Load Adjustment

Dynamic load adjustment for listener threads is based on the following `<activation-config>` properties:

- `ListenerThreadMaxIdleDuration`

- `ListenerThreadMinBusyDuration`

- `ReceiverThreads`

The `orion-ejb-jar.xml` demo file contains comments describing the `<activation-config>` properties. For information on MDB configuration, including dynamic load adjustment for MDB instances, see the Oracle Containers for J2EE Enterprise JavaBeans Developer's Guide.

### 3.4.4 Using Logical Names to Reference Resources

This section describes how you can use logical names in your client application, thereby reducing the number of dependencies on installation-specific JMS configuration within the non-OC4J-specific deployment descriptors. With this indirection, you can make your client implementation generic for any JMS configuration (and therefore independent of any specific JMS resource provider).

Using logical names enables you to make your client application code resource provider-independent. In general, configure and use logical names as follows:

1. In your client application code, use logical names for JMS destinations and connection factories.

2. Declare the logical names in the J2EE application component deployment descriptors, such as `application-client.xml` and `ejb-jar.xml`.

3. Map the logical names to explicit JNDI locations in the OC4J-specific application component deployment descriptors, such as `orion-application-client.xml` and `orion-ejb-jar.xml`.

Configuring and using logical names is discussed and demonstrated in the How-To documents and the .java and .xml files available at: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

Download and unzip one of the how-to-gjra-with-xxx.zip files, where xxx is the name of the resource provider.

This section describes the following topics:

- How to Declare Logical Names

- Mapping Logical Names to Explicit JNDI Locations

- JNDI Naming Property Setup for Java Application Clients

- Client Sends JMS Message Using Logical Names

The client uses JMS destinations and connection factories to send and receive messages. The recommended method for a client to retrieve a JMS destination object or connection factory is by using a logical name (an environment entry). Using direct JNDI locations should generally not be used unless logical names are not suitable, or some other mechanism is used to maintain the application's portability.

#### 3.4.4.1 How to Declare Logical Names

To use a logical name in your application code, you must declare the logical name in one of the following XML deployment files before the application is deployed:

- A standalone Java client—in the `application-client.xml` file

- An EJB —the `ejb-jar.xml` file

- For a JSP or servlet —the `web.xml` file

This is covered in the How-To documents available at: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`. Under "Developing the Application Components" look at task #2 "Declare Logical Names for JMS Resources".

Declare logical names for connection factories and destinations as follows:

- Declare a logical name for a connection factory using a `<resource-ref>` element.

  - Specify the logical name for the connection factory in the `<res-ref-name>` element. This is the link-key for arrows #1 and #6 in Figure 3-1.

  - Specify the connection factory class type in the `<res-type>` element as one of the following:

    - `javax.jms.ConnectionFactory`

    - `javax.jms.QueueConnectionFactory`

    - `javax.jms.TopicConnectionFactory`

  - Specify the authentication responsibility (`Container` or `Application`) in the `<res-auth>` element.

  - Specify the sharing scope (`Shareable` or `Unshareable`) in the `<res-sharing-scope>` element.

- Declare a logical name for a JMS destination using a `<message-destination-ref` element.

  - Specify the logical name for the destination in the `<message-destination-ref-name>` element. This is the link-key for arrows #2 and #8 in Figure 3-1.

  - Specify the destination type in the `<message-destination-ref-type>` element as either `javax.jms.Queue` or `javax.jms.Topic`.

  - Specify whether the client will produce messages to this destination, consume messages from this destination, or both by setting the `<message-destination-usage>` element to `Produces`, `Consumes`, or `ConsumesProduces`.

Example

The following example illustrates how to specify logical names for a queue. In the example, `jms/PlayerConnectionFactory` is the logical name for the connection factory and `jms/PlayerCommandDestination` is the logical name for the destination queue. This example is from the `application-client.xml` file in the demo set.

    <resource-ref>
      <res-ref-name>jms/PlayerConnectionFactory</res-ref-name>
      <res-type>javax.jms.ConnectionFactory</res-type>
      <res-auth>Application</res-auth>
    </resource-ref>
    <message-destination-ref>
      <message-destination-ref-name>jms/PlayerCommandDest</message-destination-ref-name>
      <message-destination-type>javax.jms.Queue</message-destination-type>
      <message-destination-usage>Produces</message-destination-usage>
    </message-destination-ref>

A full example of specifying logical names, with descriptive comments, is included in the demo at: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

Drill down to the following files: `/src/client/META-INF/application-client.xml`

and

`/src/ejb/META-INF/ejb-jar.xml`

For a list of the How-To documents and demo sets and their URLs, see "JMS How-To Documents and Demo Sets".

#### 3.4.4.2 Mapping Logical Names to Explicit JNDI Locations

After the logical names are created, the logical names must be mapped to the JNDI locations of resources. Normally, the deployer sets these up. This mapping is defined in one of the following OC4J deployment descriptor files:

- For a standalone Java client, the mapping is defined in the client's `orion-application-client.xml` file.

- For an EJB, the mapping is defined in the EJB's `orion-ejb-jar.xml` file.

- For a JSP or a servlet, the mapping is defined in the `orion-web.xml` file of the JSP or the servlet.

The logical names in the application component's deployment descriptor are mapped as follows:

- For connection factories, the logical name (declared in a `<resource-ref>` element) is mapped to a JNDI location using a `<resource-ref-mapping>` element. This is represented by arrows #6 and #5 in Figure 3-1.

- For destinations, the logical name, declared via a `<message-destination-ref>` element, is mapped to a JNDI location using a `<message-destination-ref-mapping>` element. This is represented by arrows #8 and #7 in Figure 3-1.

See the following sections for how the mapping occurs for the three OEMS JMS quality of service options and how application components use this naming convention:

- Resource Naming for OEMS JMS In-Memory and File-Based

- Resource Naming for OEMS JMS Database

- JNDI Naming Property Setup for Java Application Clients

- Client Sends JMS Message Using Logical Names

#### 3.4.4.3 JNDI Naming Property Setup for Java Application Clients

In an OC4J standalone environment, a Java application client accesses an OEMS JMS destination object by defining the following properties in the `jndi.properties` file:

    java.naming.factory.initial=
       com.evermind.server.ApplicationClientInitialContextFactory
    java.naming.provider.url=ormi://myhost/myApplicationDeploymentName
    java.naming.security.principal=oc4jadmin
    java.naming.security.credentials=welcome

If you wish to specify the port, use the optional `:port` element as follows:

    java.naming.provider.url=ormi://myhost:port/myApplicationDeploymentName

The default RMI port is `23791`.

You must:

- Use the `ApplicationClientInitialContextFactory` as your initial context factory object.

- Supply the standalone OC4J host and port, and the application deployment name in the provider URL.

In the Oracle Application Server, a Java application client accesses an OEMS JMS destination object by defining the following properties in the `jndi.properties` file:

    java.naming.factory.initial=
       com.evermind.server.ApplicationClientInitialContextFactory
    java.naming.provider.url=opmn:ormi://$HOST:$OPMN_REQUEST_PORT:$OC4J_INSTANCE/myApplicationDeploymentName
    java.naming.security.principal=oc4jadmin
    java.naming.security.credentials=welcome

- Use the `ApplicationClientInitialContextFactory` as your initial context factory object.

- Supply the OPMN host and port, the OC4J instance, and the application deployment name in the provider URL.

You can see a full example of a `jndi.properties` file at: `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

Drill down to the following file:

`/src/client/jndi.properties`

#### 3.4.4.4 Client Sends JMS Message Using Logical Names

After the resources have been defined and the JNDI properties configured, the client must perform the following steps to send a JMS message. These steps summarize the procedure shown in "Sending and Receiving JMS Messages".

1. Retrieve both the configured JMS destination and its connection factory using a JNDI lookup.

2. Create a connection from the connection factory.

3. Create a session over the connection.

4. Providing the retrieved JMS destination, create a message producer.

5. Create the message.

6. Send the message using the message producer.

7. Close the connection.

### 3.4.5 Required Class Path for Application Clients Using JMS Connector Lookup

When using the JMS Connector from an application client, the JAR files that must be included in the class path are listed inTable 3-10, "Client-side JAR Files Required for JMS Connector Lookup".

Table 3-10 Client-side JAR Files Required for JMS Connector Lookup

JAR | ORACLE_HOME Path
--- | ---
`oc4jclient.jar` | `/j2ee/<instance>`
`jta.jar` | `/j2ee/<instance>/lib`
`jms.jar` | `/j2ee/<instance>/lib`
`jndi.jar` | `/j2ee/<instance>/lib`
`javax77.jar` | `/j2ee/<instance>/lib`
`adminclient.jar` | `/j2ee/<instance>/lib`
`oc4j-internal.jar` | `/j2ee/<instance>/lib`
`connector.jar` | `/j2ee/<instance>/lib`
`jmxri.jar` | `/j2ee/<instance>/lib`
`jazncore.jar` | `/j2ee/<instance>`
`oc4j.jar` | `/j2ee/<instance>`

## 3.5 Using High Availability and Clustering for OEMS JMS

A highly available JMS server provides a guarantee that JMS requests will be serviced with no interruptions because of software or hardware failures. One way to achieve high availability is through fail-over; if one instance of the server fails, then a combination of software, hardware, and infrastructure mechanisms causes another instance of the server to take over the servicing of requests.

For information about high availability, see the Oracle Application Server High Availability Guide.

Table 3-11, "High Availability Summary" summarizes the support for high availability in OEMS JMS.

Table 3-11 High Availability Summary

Feature | Database | In-Memory and File-Based
--- | --- | ---
High availability | RAC + OPMN | OPMN
Configuration | RAC configuration, resource provider configuration | Dedicated JMS server, `jms.xml` configuration, `opmn.xml` configuration
Message store | On RAC database | In dedicated JMS server/persistence files
Failover | Same or different machine (depending on RAC) | Same or different machine within Oracle Application Server Cold Failover Cluster (Midtier)

OEMS JMS clustering provides an environment where JMS applications deployed in this type of environment can load balance JMS requests across multiple OC4J instances or processes. Clustering of stateless applications is trivial: the application is deployed on multiple servers, and user requests are routed to one of them.

JMS is a stateful API. Both the JMS client and the JMS server contain state about each other, which includes information about connections, sessions, and durable subscriptions. Users can configure their environment and use a few simple techniques when writing their applications to make them cluster-friendly.

The following sections discuss how to achieve high availability and clustering with OEMS JMS:

- Configuring OEMS JMS In-Memory and File-Based High Availability

- Configuring OEMS JMS Database High Availability

- Failover Scenarios When Using a RAC Database

- Sample Code for Connection Recovery

- Clustering Best Practices

### 3.5.1 Configuring OEMS JMS In-Memory and File-Based High Availability

OEMS JMS clustering normally implies that an application deployed in this type of environment is able to load balance messages across multiple instances of OC4J. There is also a degree of high availability in this environment because the container processes can be distributed across multiple nodes. If any of the processes or nodes goes down, then the processes on an alternate node continue to service messages.

This section describes the following OEMS JMS clustering topics:

- Terminology

- Distributed Destinations

  In this configuration, all factories and destinations are defined on all OC4J instances. Each OC4J instance has a separate copy of each destination.

  This configuration is good for high-throughput applications where requests must be load balanced across OC4J instances. No configuration changes are required for this scenario.

- Cold Failover Cluster

  This configuration is a two-node cluster. Only one node is active at any time. The second node is made active if the first node fails.

- Dedicated JMS Server

  In this configuration, a single JVM within a single OC4J instance is dedicated as the JMS server. All other OC4J instances that are hosting JMS clients forward their JMS requests to the dedicated JMS server.

  This configuration is the easiest to maintain and troubleshoot and should be suitable for the majority of JMS applications, especially those where message ordering is a requirement.

- Custom Topologies

  This section discusses reasons for using custom topologies, lists requirements and impacts of various topology choices, and explains how custom topologies can be created.

  Custom topologies by their very nature are more complex to understand and use correctly, and involve more configuration effort. They should only be used when none of the standard configurations is adequate.

#### 3.5.1.1 Terminology

The terms introduced here are explained in the Oracle Application Server High Availability Guide and the Oracle Process Manager and Notification Server Administrator's Guide.

- OHS—Oracle HTTP Server

- OracleAS Cluster—A grouping of similarly configured Oracle Application Server instances

- Oracle Application Server Instance—Represents an installation of Oracle Application Server (that is, an `ORACLE_HOME`)

- OC4J Instance—Within an Oracle Application Server instance there can be multiple OC4J instances.

- Factory—Denotes a JMS connection factory

- Destination —Denotes a JMS destination

#### 3.5.1.2 Distributed Destinations

In this configuration, OHS services HTTP requests and load balances them across two or more Oracle Application Server instances in an Oracle Application Server cluster.

Each copy of the destinations is unique and is not replicated or synchronized across OC4J instances. Destinations can be persistent or in-memory. A message enqueued to one OC4J instance can be dequeued only from that OC4J instance.

This type of deployment has several advantages:

- High throughput is achieved because applications and the JMS server are both running inside the same JVM and no interprocess communication is necessary.

- Load balancing promotes high throughput as well as high availability.

- There is no single point of failure. As long as one OC4J process is available, then requests can be processed.

- Oracle Application Server instances can be clustered without impacting JMS operations.

- Destination objects can be in-memory or file-based.

Figure 3-2 Distributed Destinations

Description of "Figure 3-2 Distributed Destinations"

Configuring a Distributed Destinations Cluster

Within each Oracle Application Server instance, two OC4J instances have been defined. Each of these OC4J instances is running a separate application. In other words, OC4J instance #1 (`Home1`) is running Application #1 while OC4J instance #2 (`Home2`) is running Application #2. Remember, each OC4J instance can be configured to run multiple JVMs, allowing the application to scale across these multiple JVMs.

Within an Oracle Application Server cluster, the configuration information for each Oracle Application Server instance is identical (except for the instance-specific information such as host name, port numbers, and so on). This means that Application #1 deployed to OC4J instance #1 in Oracle Application Server instance #1 is also deployed on OC4J instance #1 in Oracle Application Server instance #2. This type of architecture allows for load balancing of messages across multiple Oracle Application Server instances—as well as high availability of the JMS application, especially if Oracle Application Server instance #2 is deployed to another node to ensure against hardware failure.

The sender and receiver of each application must be deployed together on an OC4J instance. In other words, a message enqueued to the JMS Server in one OC4J process can be dequeued only from that OC4J process.

All factories and destinations are defined on all OC4J processes. Each OC4J process has a separate copy of each destination. The copies of destinations are not replicated or synchronized. So, in the diagram, Application #1 is writing to a destination called `myQueue1`. This destination physically exists in two locations (Oracle Application Server instance #1 and #2) and is managed by the respective JMS servers in each OC4J instance.

Note that this type of JMS deployment is suited only for specific types of JMS applications. Assuming that message order is not a concern, messages are enqueued onto distributed queues of the same name. Given the semantics of JMS point-to-point messaging, messages must not be duplicated across multiple queues. In the preceding case, messages are sent to whatever queue the load balancing algorithm determines, and the MDBs dequeue them as they arrive.

#### 3.5.1.3 Cold Failover Cluster

This configuration is a two-node cluster. Only one node is active at any time. The second node is made active if the first node fails. For larger clusters, Cold Failover Clustering can be used in combination with the dedicated JMS server configuration described in the next section by having two nodes configured to be the dedicated JMS server, but having only one of them active at any given time. For Cold Failover documentation, see the Oracle Application Server High Availability Guide.

Configuring a Cold Failover Cluster

Configure both nodes identically as described in the following example. Modify the `jms.xml` file for both OC4J instances. Set the host parameter in the `jms-server` to be:

    <jms-server host=vmt.my.company.com port="9127">
    ….
    ….
    </jms-server>

When using file-based message persistence for a queue, the file must be located on a shared disk that is accessible by both nodes. The shared disk must fail over with the virtual IP when failing over from one node to the other. Configure the `persistence-file` as follows:

    <queue name="Demo Queue" location="jms/demoQueue" persistence-file="/path/to/shared_file_system/demoQueueFile">
            <description>A dummy queue</description>
    </queue>

Stop and Start

On each node, use the following commands to stop and start:

    $ORACLE_HOME/opmn/bin/opmnctl stopall
    $ORACLE_HOME/opmn/bin/opmnctl startall

#### 3.5.1.4 Dedicated JMS Server

In this configuration, a single OC4J instance is configured as the dedicated JMS server within an Oracle Application Server clustered environment. This OC4J instance handles all messages, thus message ordering is always maintained. All JMS applications use this dedicated server to host their connection factories and destinations, and to service their enqueue and dequeue requests.

Only one OC4J JVM is acting as the dedicated JMS provider for all JMS applications within the cluster. This is achieved by limiting the JMS port range in the `opmn.xml` file to only one port for the dedicated OC4J instance.

Although this diagram shows the active JMS server in the OC4J `Home` instance, Oracle recommends that the JMS provider be hosted in its own OC4J instance. For example, although `Home` is the default OC4J instance running after an Oracle Application Server installation, you should create a second OC4J instance with the Oracle Enterprise Manager 10g Application Server Control Console. In the `opmn.xml` file example following, we have created an OC4J instance called `JMSserver`.

Figure 3-3 Dedicated JMS Server

Description of "Figure 3-3 Dedicated JMS Server"

After creating an OC4J instance called `JMSserver`, we must make the following two changes to the `opmn.xml` file for this Oracle Application Server instance:

1. Make sure that only one JVM is started for this OC4J instance (`JMSserver`).

   The single JVM in the OC4J instance ensures that other JVMs will not attempt to use the same set of persistent files.

2. Specify only one value for the JMS port range for this instance.

   The single port value ensures that OPMN always assigns this value to the dedicated JMS server. This port value is used to define the connection factory in the `jms.xml` file that other OC4J instances will use to connect to the dedicated JMS server.

For more information on OPMN and dynamic port assignments, see the Oracle Process Manager and Notification Server Administrator's Guide.

##### 3.5.1.4.1 Modifying the OPMN Configuration

The following XML from the `opmn.xml` file shows what changes must be made and how to find where to make these changes.

- Assuming an OC4J instance has been created through Application Server Control Console called `JMSserver`, then the line denoted by (1) demonstrates where to locate the start of the `JMSserver` definition.

- The line denoted by (2) is the JMS port range that OPMN uses when assigning JMS ports to OC4J JVMs. For the desired dedicated OC4J instance that acts as your JMS provider, narrow this range down to one value. In this example, the original range was from `3701-3800`. In our connection factory definitions, we know the port to use by configuring this value as `3701-3701`.

- The line denoted by (3) defines the number of JVMs that will be in the `JMSserver` default group. By default, this value is set to `1`. This value must always be `1`.

    <ias-component id="OC4J">
      (1) <process-type id="JMSserver" module-id="OC4J" status="enabled">
         <module-data>
           <category id="start-parameters">
             <data id="java-options" value="-server
               -Djava.security.policy=$ORACLE_HOME/j2ee/home/config/java2.policy
               -Djava.awt.headless=true
             "/>
           </category>
           <category id="stop-parameters">
             <data id="java-options"
               value="-Djava.security.policy=
                 $ORACLE_HOME/j2ee/home/config/java2.policy
               -Djava.awt.headless=true"/>
           </category>
        </module-data>
        <start timeout="600" retry="2"/>
        <stop timeout="120"/>
        <restart timeout="720" retry="2"/>
        <port id="ajp" range="3000-3100"/>
        <port id="rmi" range="3201-3300"/>
        (2) <port id="jms" range="3701-3701"/>
        (3) <process-set id="default_group" numprocs="1"/>
      </process-type>
    </ias-component>

##### 3.5.1.4.2 Configuring OEMS JMS

As already described in this scenario, one of the OC4J instances is dedicated as the JMS server. Other OC4J instances and standalone JMS clients running outside OC4J must be set up to forward JMS requests to the dedicated JMS server. All connection factories and destinations are defined in the JMS server instance's `jms.xml` file. This `jms.xml` file should then be copied to all the other OC4J instances that will be communicating with the JMS server.

The connection factories configured in the `jms.xml` file on the dedicated JMS server must specify, explicitly, the host name and the port number of the server. The host name and port number in `jms.xml` must match the host name and single port number defined by OPMN for the dedicated server as discussed above. The same connection factory configuration must also be used in all other OC4J instances so that they all point to the dedicated JMS server for their operations.

Thus, if the dedicated JMS server runs on `host1`, port `3701`, then all connection factories defined within the `jms.xml` file for each OC4J instance in the cluster must point to `host1`, port `3701`—where this port is the single port available in the `opmn.xml` file used in the dedicated OC4J instance (in our example, `JMSserver`) used for the dedicated JMS server.

The destinations configured in the `jms.xml` file on the dedicated JMS server should also be configured on all other OC4J instances; the physical store for these destinations, however, is on the dedicated JMS server.

Queue Connection Factory Definition Example

Here is an example for defining a queue connection factory in the `jms.xml` file of the dedicated server:

    <!-- Queue connection factory -->
    <queue-connection-factory name="jms/MyQueueConnectionFactory"
              host="host1" port="3701"
              location="jms/MyQueueConnectionFactory"/>

Administrative changes (that is, adding a new destination object) should be made to the dedicated JMS server's `jms.xml` file. These changes should then be made in the `jms.xml` files of all other OC4J instances running JMS applications. Changes can be made either by hand or by copying the dedicated JMS server's `jms.xml` file to the other OC4J instances.

##### 3.5.1.4.3 Deploying Applications

The user decides where the JMS applications will actually be deployed. Although the dedicated JMS server services JMS requests, it can also execute deployed JMS applications. JMS applications can also be deployed to other OC4J instances (that is, `Home`).

Remember, the `jms.xml` file from the dedicated JMS server must be propagated to all OC4J instances where JMS applications are to be deployed. JMS applications can also be deployed to standalone JMS clients running in separate JVMs.

##### 3.5.1.4.4 High Availability

OPMN provides the failover mechanism to keep the dedicated JMS server up and running. If for some reason the JMS server fails, then OPMN detects this and restarts the JVM. If a hardware failure occurs, then the only way to recover messages is to have the persisted destinations hosted on a network file system. An OC4J instance can then be brought up and configured to point to these persisted files.

See the Oracle Process Manager and Notification Server Administrator's Guide for more information on how OPMN manages Oracle Application Server processes.

#### 3.5.1.5 Custom Topologies

In addition to the previously discussed configurations, OEMS JMS can be configured into arbitrary user-defined topologies.

##### 3.5.1.5.1 Mechanisms

This section discusses the mechanisms that allow custom topologies to be created and to function. These mechanisms are already defined in other places in this document, however this section also covers some of the finer points that need to be understood when using a custom topology.

Using a JMS server other than the one in the local OC4J JVM requires a connection factory that references the desired JMS server. This is done by way of a host and port mapping.

First, the JMS server must be associated with a host and port. Usually, the host is the single host/IP address of the machine on which the JMS server is run. In the case of a machine with multiple host/IP addresses, all addresses will be associated with the JMS server unless a specific address is specified via the "host" attribute of the `<jms-server>` element in the `jms.xml` file. The `port` is `9127` unless a different value is specified via the "`port`" attribute. See the `<jms-server>` entry in Table 3-2, "Configuration Elements", and also see "Configuring Ports" . When OPMN is used, the "`port`" attribute is ignored and port assignment is handled automatically from a range of port values set in the `opmn.xml` file. See "Modifying the OPMN Configuration" .

Once the host and port have been designated for each JMS server, then connection factories can be made to reference specific JMS servers. The first step in making a connection factory reference a specific JMS server is to set the `host` attribute of the connection factory element to be the same as the host/IP address of the given JMS server. See `<connection-factory>`, `<xa-connection-factory>`, and the other connection factory elements in Table 3-2, "Configuration Elements". When making a connection factory reference a JMS server on the same machine where that machine has a single host/IP address, this step may be skipped (the "`host`" attribute may be left out). The next step in making a connection factory reference a specific JMS server is to set the "`port`" attribute of the connection factory element to be the same as the port of the given JMS server. If the port is `9127`, this step may be skipped (the "`port`" attribute may be left out).

If connection factory CF1 has been configured (as described in the previous paragraph) to reference JMS server JMS1, then a connection created from CF1 is a connection to JMS1. All operations performed via that connection will go to JMS1. It is not possible to use that connection to interact with any other JMS server. (It is not even possible to use that connection to interact with the JMS server running in the local JVM, unless it happens to be JMS1.) Likewise, if that connection is used to create a session, and that session to create a message producer, then that session and message producer are both connected to JMS1. All messages sent via that message producer will go to JMS1, will be stored (in memory or file) by JMS1, and can only be received or browsed from JMS1 (via a message consumer or queue browser that is connected to JMS1). Note that this JMS server association does not extend to `javax.jms.Message` objects. Message objects created or received from a session or message producer associated with one JMS server may be sent using any message producer. For example, an application could receive a message from a physical destination maintained by JMS server "JMS1" using a message consumer associated with "JMS1", and then send that message to a physical destination maintained by JMS server "JMS2" using a message producer associated with "JMS2".

When dealing with multiple JMS servers, it is necessary to draw a distinction between physical destinations (physical locations where messages are stored), destination configuration (elements/attributes in `jms.xml`) and destination admin objects (Java objects looked up in JNDI).

From the perspective of a JMS server:

- A name (whether from a destination configuration or from a destination admin object) uniquely identifies a physical destination - one controlled solely by the given JMS server.

- The `persistence-file` attribute (or its absence) tells the JMS server where it should persist the messages for a given physical destination.

- The location attribute tells the JMS server where to bind a destination admin object (containing the value of the `name` attribute) in JNDI in the local JVM.

From the perspective of a JMS client:

- Destination admin objects do not contain JNDI locations. Instead, they are looked-up at a JNDI location.

- Destination admin objects do not have any persistence file settings. Instead, the persistence file (if any) used for a given physical destination is determined by the JMS server that controls that physical destination.

- Destination admin objects contain only a name, and names do not uniquely identify a physical destination. When interacting with JMS server JMS1, a destination admin object will be considered to be a reference to a physical destination controlled by JMS1. When interacting with JMS server JMS2, that same destination admin object will be considered to be a reference to a different physical destination - one controlled by JMS2. (If, when interacting with a JMS server, a destination admin object is used whose name does not match the name of any physical destination on the given JMS server, the operation will fail.)

For example, given an excerpt from JMS server JMS1's `jms.xml` file:

       <queue name="queue1"
              location="jms/alpha"
              persistence-file="foo">
       </queue>

And given an excerpt from JMS server JMS2's `jms.xml` file:

       <queue name="queue1"          location="jms/omega"          persistence-file="bar">   </queue>

       <queue name="queue2"
              location="jms/alpha">
       </queue>

In Table 3-12, "Results for Various Message Scenarios", if a destination is looked-up from the server in column 1 using the JNDI location from column 2, and then a message producer connected to the server in column 3 is used to send a PERSISTENT message, the result is as described in the final column.

Table 3-12 Results for Various Message Scenarios

Destination looked-up in the same JVM as | JNDI location used to look up destination | Message producer connected to | Result (physical destination that receives message, or error)
--- | --- | --- | ---
JMS1 | jms/alpha | JMS1 | JMS1's "queue1", persisted to file "foo"
JMS1 | jms/alpha | JMS2 | JMS2's "queue1", persisted to file "bar"
JMS2 | jms/alpha | JMS2 | JMS2's "queue2", stored in memory on JMS2
JMS2 | jms/alpha | JMS1 | Error (JMS1 does not have a "queue2")
JMS1 | jms/omega | don't care | Error looking up "jms/omega" in JNDI
JMS2 | jms/omega | JMS1 | JMS1's "queue1", persisted to file "foo"
JMS2 | jms/omega | JMS2 | JMS2's "queue1", persisted to file "bar"

Note that the above example (and the connection factories in the "Distributed Destinations" configuration) bind/require different values for the same JNDI location in different JVMs, and therefore require that JNDI values not be automatically propagated from one JVM to another.

When using the following combination:

- OPMN (automatic JMS port assignment)

- One or more dedicated JMS servers

- Multiple OC4J instances per machine

Care should be taken to ensure that:

- The range of available JMS ports is just enough for the number of JMS servers on the given machine. This guarantees that the dedicated JMS server port number actually gets assigned to one of the available JMS servers.

- The persistence files (if any) for the destination(s) controlled by the dedicated JMS serve are specified in the `jms.xml` file(s) using absolute paths. If a path is relative to the OC4J instance, then previously persisted messages would be lost after a server restart when OPMN assigns the dedicated JMS server port number to a JMS server in a different OC4J instance than it did after the previous restart.

##### 3.5.1.5.2 Considerations

The "Dedicated JMS Server" and "Distributed Destinations" configurations are the only configurations where each instance of an arbitrary JMS application is guaranteed to only ever communicate with a single JMS server. The considerations discussed in this section do not apply to those scenarios. They also do not apply to other scenarios where it can be guaranteed that a JMS application instance only ever communicates with a single JMS server.

For example, if all instances of application A use JMS server #1 and all instances of application B use JMS server #2, then the following considerations are not applicable.

In other scenarios, where a single JMS application instance interacts with two or more JMS servers, there are several consequences:

- There is an application-complexity impact:

  Since a JMS server is selected based on the connection factory (and its derived objects), using multiple JMS servers from a single application instance requires the use of multiple connection factories (and derived objects such as sessions, consumers and producers). For example, if an application uses producer A to enqueue a message to JMS server #1, it is not possible to also use producer A to enqueue a message to JMS server #2. Instead, a different producer, derived from a different connection factory than the one from which producer A was derived, must be used. (To be specific, a producer derived from a connection factory associated with JMS server #2 must be used.) This also means that using multiple JMS servers may not be possible with a pre-existing JMS application unless the application already accommodates (or can be modified to accommodate) this prerequisite.

- There is a performance impact:

  Since two different JMS servers represent two different resource managers, global transactions involving two JMS servers will always require two-phase commit, even if no other resource types (such as JDBC) are used during the transaction. Even if two-phase commit was already required for a given transaction, when more resource managers participate in a transaction, the cost (in performance) of the transaction goes up. However, using multiple JMS servers is still a performance win in many scenarios since it can be used to offload work from potential bottlenecks (such as a single, dedicated JMS server) and increase both parallelism and locality.

These same considerations also apply if a single JMS application instance is using two different JMS resource providers. For example, an application might use OEMS JMS In-Memory for memory-based or file-based persistence and also use OEMS JMS Database for database-backed persistence.

##### 3.5.1.5.3 Cases

This section shows two example situations driven by application-specific messaging requirements, along with custom topologies that could be used to improve throughput in each case. These examples should not be considered exhaustive, either in terms of situations you may encounter or in topologies that can be created.

Case #1: Only some destinations need global consistency:

It may be that some destinations must provide global consistency, as provided by the "Dedicated JMS Server" configuration, and other destinations have no such requirement. In that case, it is not necessary to pay the expense of global consistency (routing all messages through a single JMS server) for the destinations that do not require it and could instead be locally partitioned, such as in the "Distributed Destinations" configuration.

Say that destinations A and B need global consistency, and that destinations C and D do not. In that case, all jms.xml files define all four destinations. One machine is selected to host the dedicated JMS server for destinations A and B. The dedicated JMS server must have fixed host and port values in order to allow connection factories to reference it. At least two connection factories are defined in the jms.xml files, one that references the dedicated JMS server (that is, with a fixed host and port value) and one that references the JMS server in the local JVM (that is, with the default host and port values). In order to access destinations A and B (and maintain global consistency), the Java code must use a connection factory that references the dedicated JMS server. In order to access destinations C and D, the Java code must use a connection factory that references the JMS server in the local JVM.

Case #2: Using multiple dedicated JMS servers for load-balancing:

In the previous example, two destinations (A and B) needed global consistency. This requires that destination A has a dedicated JMS server and that destination B has a dedicated JMS server, but does not require that those two JMS servers be the same. When multiple destinations requiring global consistency are heavily used, it may be worth while to divide the load of those destinations across multiple dedicated JMS servers. This is especially true for destinations that tend to not be involved in a common transaction and/or when a multi-destination dedicated JMS server is acting as a system bottleneck.

For this case, all jms.xml files define all four destinations. One machine is selected to host the dedicated JMS server for destination A. Another machine (or another JVM on the same machine) is selected to host the dedicated JMS server for destination B. Both dedicated JMS servers must have fixed host and port values in order to allow connection factories to reference them. At least three connection factories are defined in the jms.xml files, one that references the dedicated JMS server for destination A, one that references the dedicated JMS server for destination B, and one that references the JMS server in the local JVM. In order to access destination A, the Java code must use a connection factory that references the dedicated JMS server for destination A. In order to access destination B, the Java code must use a connection factory that references the dedicated JMS server for destination B. In order to access destinations C and D, the Java code must use a connection factory that references the JMS server in the local JVM.

### 3.5.2 Configuring OEMS JMS Database High Availability

To enable high availability the OEMS JMS Database option, run the following:

- Run an Oracle database that contains the AQ queues and topics in RAC-mode. This ensures that the database is highly available.

- Run Oracle Application Server in OPMN-mode. This ensures that the application servers (and applications deployed on them) are highly available.

Each application instance in an Oracle Application Server cluster uses OC4J resource providers to point to the back end Oracle database, which is operating in RAC-mode. JMS operations invoked on objects derived from these resource providers are directed to the real application clusters (RAC) database.

If a failure of the application occurs, then state information in the application is lost (that is, state of connections, sessions, and messages not yet committed). As the application server is restarted, the applications must re-create their JMS state appropriately and resume operations.

If network failover of a back-end database occurs, where the database is a non-RAC database, then state information in the server is lost (that is, state of transactions not yet committed). Additionally, the JMS objects (connection factories, destination objects, connections, sessions, and so on) inside the application may also become invalid.

After the failure of the database occurs, those JMS objects will throw exceptions whenever the application code attempts to use them. In order to recover, the application must recreate any and all JMS objects which are throwing such exceptions. This includes relooking up connection factories using JNDI.

#### 3.5.2.1 Failover Scenarios When Using a RAC Database

An application that uses a RAC database must handle database failover scenarios. There are two types of failover scenarios, as described in Chapter 4, "Data Sources". The following sections demonstrate how to handle each failover scenario:

- RAC Network Failover

- Transparent Application Failover (TAF)

  Note: The `RAC-enabled` attribute of a data source is discussed in Chapter 4, "Data Sources". For more information on using this flag with an infrastructure database, see the Oracle Application Server High Availability Guide.

##### 3.5.2.1.1 RAC Network Failover

A standalone client running against an RAC database must write code to obtain the connection again, by invoking the API `com.evermind.sql.DbUtil.oracleFatalError()`, to determine if the connection object is invalid. It must then reestablish the database connection if necessary. The `oracleFatalError()` method detects if the SQL error thrown by the database during network failover is a fatal error. This method takes in the SQL error and the database connection, and returns `true` if the error is a fatal error. If `true`, you may wish to aggressively roll back transactions and re-create the JMS state (such as connections, session, and messages that were lost).

The following example outlines the logic:

    getMessage(QueueSesssion session) {
        try {
            Message msgRec = null;
            QueueReceiver rcvr = session.createReceiver(rcvrQueue);
            msgRec = rcvr.receive();
        } catch(Exception exc) {
            while (exc instanceof JMSException) {
               exc = ((JMSException) exc).getLinkedException();
            }
            if (exc instanceof SQLException) {
                sql_ex = (SQLException) exc;
                db_conn = (oracle.jms.AQjmsSession) session.getDBConnection();
                if ((DbUtil.oracleFatalError(sql_ex, db_conn)) {
                    // failover logic
                }
            }
        }
    }

##### 3.5.2.1.2 Transparent Application Failover (TAF)

In most cases where TAF is configured, the application does not notice that failover to another database instance has occurred. So, you need not do anything to recover from failure.

However, in some cases, OC4J throws an ORA error when a failure occurs. The JMS client passes these errors to the user as a `JMSException` with a linked SQL exception. In this case, do one or more of the following:

- As described in "RAC Network Failover", you can use the `DbUtil.oracleFatalError` method to determine if the error is a fatal error. If it is not a fatal error, then the client recovers by sleeping for a short time and then retrying the current operation.

- You can recover from failback and transient errors caused by incomplete failover by trying to use the JMS connection after a short time. Waiting allows the database failover to recover from the failure and reinstate itself.

- In the case of transaction exceptions (such as "Transaction must roll back" (ORA-25402) or "Transaction status unknown" (ORA-25405)) you must roll back the current operation and retry all operations past the last commit. The connection is not usable until the cause of the exception is dealt with. If this retry fails, then close and re-create all connections and retry all non committed operations.

### 3.5.3 Sample Code for Connection Recovery

The following example shows OEMS JMS application code that is can be used with any of the persistence options, for a queue that is tolerant to intermittent connection failures, such as may happen during network outages, server reboots, JMS server failover, and other situations.

     while (!shutdown) {
            Context ctx = new InitialContext();

            // get the queue connection factory
            QueueConnectionFactory qcf =
                            (QueueConnectionFactory) ctx.lookup(QCF_NAME);

            // get the queue
            Queue q = (Queue) ctx.lookup(Q_NAME);

            ctx.close();

            QueueConnection qc = null;
            try {
                // create a queue connection, session, sender and receiver
                qc = qcf.createQueueConnection();
                QueueSession qs = qc.createQueueSession(true, 0);
                QueueSender snd = qs.createSender(q);
                QueueReceiver rcv = qs.createReceiver(q);

                // start the queue connection
                qc.start();

                // receive requests using the queue receiver and send
                // replies using the queue sender
                while (!done) {
                    Message request = rcv.receive();
                    Message reply = qs.createMessage();

                    // put code here to process request and construct reply

                    snd.send(reply);
                    qs.commit();
                }
            } catch (JMSException ex) {
                if (transientServerFailure) {
                    // retry
                } else {
                    shutdown = true;
                }
            } finally {
               // close the queue connection
               if (qc != null) qc.close();
            }
        }

#### 3.5.3.1 J2CA Configuration for Connection Recovery

Note that connection pooling means that when a connection is closed by the application, the physical connection is not actually closed by the connector but is instead returned to the connection pool. If a connection fails, this can result in an invalid connection being returned to the pool. Subsequent attempts to create a new connection may then obtain an invalid connection, negating the value of the above style of code. In order to make failover reliable, connection pooling should be disabled for the connection factory used to create the connection. This is done by modifying the the connection factory's `<connector-factory>` element in the `oc4j-ra.xml` file to include the following:

        <connection-pooling use="none">
        </connection-pooling>

### 3.5.4 Clustering Best Practices

- Minimize JMS client-side state.

  - Perform work in transacted sessions.

  - Save/checkpoint intermediate program state in JMS queues/topics for full recoverability.

  - Do not depend on J2EE application state to be serializable or recoverable across JVM boundaries. Always use transient member variables for JMS objects, and write passivate/activate and serialize/deserialize functions that save and recover JMS state appropriately.

- Do not use nondurable subscriptions on topics.

  - Nondurable topic subscriptions duplicate messages per active subscriber. Clustering and load-balancing creates multiple application instances. If the application creates a nondurable subscriber, it causes the duplication of each message published to the topic. This is either inefficient or semantically invalid.

  - Use only durable subscriptions for topics. Use queues whenever possible.

- Do not keep durable subscriptions alive for extended periods of time.

  - Only one instance of a durable subscription can be active at any given time. Clustering and load-balancing creates multiple application instances. If the application creates a durable subscription, only one instance of the application in the cluster succeeds. All other instances fail with a `JMSException`.

  - Create, use, and close a durable subscription in small time/code windows, minimizing the duration when the subscription is active.

  - Write application code that accommodates failure to create durable subscription due to clustering (when some other instance of the application running in a cluster is currently in the same block of code) and program appropriate back-off strategies. Do not always treat the failure to create a durable subscription as a fatal error.

## 3.6 JMS Router

This section describes the JMS Router.

### 3.6.1 Functionality

In the present complex and disparate enterprise-computing environment, a messaging infrastructure must integrate and interoperate with various messaging systems to achieve maximum connectivity.

The JMS Router provides a reliable asynchronous JMS message routing service that can bridge:

- Destinations of the same JMS provider.

- Destinations of different JMS providers.

The JMS Router guarantees the following behavior:

- For persistent JMS messages, the JMS Router guarantees exactly-once message delivery.

- For non-persistent JMS messages, the JMS Router guarantees at-most-once message delivery.

- The JMS Router guarantees the delivery of messages in the order they are received by the JMS Router from the source destination.

Users can specify a message selector to selectively route messages when creating a router job. Only the messages that satisfy the selector are routed from the source destination to the target destination by the JMS Router. The message selectors must be valid JMS message selectors. See the JMS 1.1 specification for the message selector syntax and semantics for JMS queues and topics.

The JMS Router requires that the participating JMS provider support JMS 1.1 if either the source or target of a JMS Router job is a JMS topic.

You can access the JMS 1.1 specification at: `http://java.sun.com/products/jms/docs.html`.

By bridging JMS destinations, the JMS Router provides users the following benefits:

- The application that sends messages in one messaging system and the application that receives messages in another messaging system are decoupled. It is not necessary for the two applications to be aware of messages traveling across different messaging systems.

- An application that needs to send and receive messages to or from multiple messaging systems need only connect to one messaging system and rely on the JMS Router to distribute messages across multiple messaging systems. This simplifies application code by eliminating the need to connect to multiple messaging systems, to manage global transactions with 2-PC, and to deal with message translation.

- The automatic recovery and guaranteed message delivery by the JMS Router make applications and application integration more reliable because the applications do not need to require that all involved messaging systems be alive at the same time.

### 3.6.2 JMS Providers

The JMS Router uses the JMS Connector to access the following JMS providers:

- OEMS JMS In-Memory, File-Based, and Database persistence options

- IBM WebSphere MQ V6.0 JMS, MQ V5.3 JMS with Fix Pack 8 (CSD08)

- TIBCO Enterprise for JMS version 3.1.0

- SonicMQ 6.0 JMS

The JMS Router relies on the OC4J pre-packaged standalone JMS Connector instance OracleASjms to access the OEMS JMS In-Memory and File-Based options that run in the same container as the JMS Router. Therefore, there is no need to deploy any additional adapters for routing messages to and from OEMS JMS In-Memory or File-Based Destinations.

For routing messages to and from any JMS provider other than OracleAS JMS, there must be a standalone JMS Connector deployed for the JMS provider.

The JMS Router uses the J2CA adapter's declarative container-managed sign-on mechanism for JMS provider authentication and authorization. The JMS Router runs on behalf of the role `jmsRouter`. Therefore, all the resource adapters used by the JMS Router must have a valid principal mapping with either the `<default-mapping>` element or a `<principal-mapping-entry>` element that has `jmsRouter` as `<initiating-user>` in the `oc4j-ra.xml`.

Additional information on how to use the JMS Router for OEMS JMS is available at `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`.

### 3.6.3 Configuration

This section discusses configuration with respect to the following JMS Router objects:

- Router Jobs

- Global Router Parameter(s)

- Subscription

- Log Queues and Exception Queues

The primary administration interface of the JMS Router is the JMS Router MBean. The MBean enables you to manage configuration, to start and stop individual JMS Router jobs, and to monitor the status of the jobs.

The JMS Router may also be configured statically through the `jms.xml` file.

#### 3.6.3.1 Router Jobs

The JMS Router job is defined as a message routing task to move messages from the source destination to a target destination. When processing a router job, the JMS Router dequeues messages from the source destination and enqueues the messages to the target destination.

The source and the target destinations can be either JMS queues or topics. If the source is a JMS queue, then the JMS Router moves all messages from the queue. If the source is a topic, then the JMS Router moves all messages that are published to the topic since the JMS durable subscriber was created.

Note: JMS Router jobs must not share a source, whether it is a queue or a durable subscriber.

A JMS Router job uses the objects described in Table 3-14, "JMS Router Settings".

The JMS Router uses the JMS Connector to access JMS destinations and connection factories. The JMS Router requires that source and target destinations for all JMS Router jobs exist in the accessed JMS provider, and are configured in the appropriately configured JMS Connector. For information on configuring Queues, Topics, and ConnectionFactories, see "Configuring Destination Objects and Connection Factories". For additional resource adapter configuration information, see "JMS Connector" and the Oracle Containers for J2EE Resource Adapter Administrator's Guide.

#### 3.6.3.2 Global Router Parameter(s)

The number of concurrent jobs is configurable as a JMS Router attribute `maxLocalConcurrency`. This attribute prevents a JMS Router with many active jobs from dominating the OC4J J2EE container. This also sets the upper limit on the number of JMS sessions created by JMS Connectors that are used by the JMS Router.

#### 3.6.3.3 Subscription

If the source is a JMS topic, the user may provide a durable subscriber name on the topic. The actual durable subscriber can be created before the associated router job is created. If the name of the durable subscriber is not specified, then the JMS Router creates a subscriber name based on the name of the job. If the durable subscriber associated with the subscriber name does not exist when the JMS Router starts to process the job, then the router creates the durable subscriber. The JMS Router moves all messages that are published to the topic since the durable subscriber was created.

By default, when a JMS Router job is deleted, the JMS Router attempts to remove the durable subscriber. If the JMS Router fails to remove the durable subscriber, then the user must remove it through the administration interface of the messaging system to avoid unnecessary message accumulation. Users can also optionally ask the JMS Router not to remove the durable subscriber when deleting a JMS Router job.

#### 3.6.3.4 Log Queues and Exception Queues

This section discusses log queues and exception queues.

Log Queues

The JMS Router uses queues for internal logging. Each router job must have a source log queue and a target log queue. These queues are used to ensure quality of service when processing router jobs. For the OEMS JMS In-Memory and File-Based options, the JMS Router creates log queues. For the OEMS JMS Database option and other supported non-Oracle JMS providers, a JMS queue must be created on that system, and the name of the queue must be specified when creating the router job. Log queues may be shared by multiple jobs.

Log queues for the JMS Router must exist in the accessed messaging system and must be configured in the appropriate resource adapter.

Exception Queues

When the JMS Router fails to send a message to the target destination, it blocks processing of the associated router job in order to maintain message order.

In order for the JMS Router to keep processing a job with problematic messages, users can configure the job with an exception queue into which the JMS Router can move the problematic messages in order to process the remaining messages in the source destination.

Each JMS Router job can have one exception queue, which must be a JMS queue in the same messaging system as the source destination and accessible through the same connection factory as that of the source destination. The physical JMS destination for the exception queue must exist before it is used for any JMS Router jobs. In the OEMS JMS In-Memory and File-Based options, an exception queue is already defined by default -- `Oc4jJmsExceptionQueue`.

In order for the JMS Router to move problematic messages into the exception queue, the `useExceptionQueue` flag must be set to `true` for the associated router job.

Optionally, exception queues, if configured, for the JMS Router must exist in the accessed messaging system and must be configured in the appropriate resource adapter.

#### 3.6.3.5 Configuring the JMS Router and Its Objects

The primary administration interface of the JMS Router is the JMS Router MBean. Use the MBean to manage configuration, to start and stop individual JMS Router jobs, and to monitor the status of the jobs.

This section describes the operations and settings available in JMS Router MBean.

Path to the JMS Router MBean:

OC4J:Home > Administration tab > Services > JMS Providers > Click the icon. > Select the appropriate tab. > Related Links: OracleASJMSRouter

Note: The JMS Router exports a single JMS Router MBean per OC4J instance: "`jmsrouter:j2eeType=OracleASJMSRouter`".

The following table lists and describes the operations available on the JMS Router MBean. All operations update the JMS Router dynamically and persist the changes to `jms.xml`.

Table 3-13 JMS Router MBean Operations

Operation | Description
--- | ---
`addRouterJob` | Configures a JMS Router job.
`alterRouterJob` | Alters the attributes of a JMS Router job. The default value for all parameters to alterRouterJob is to leave them unchanged.
`configureRouter` | Configures certain global parameters of the JMS Router, such as `maxLocalConcurrency`.
`pauseRouterJob` | Suspend the execution of a JMS Router job.
`removeRouterJob` | Removes a JMS Router job.
`resetRouterJob` | Resets the number of failures in the JMS Router job to zero.
`resumeRouterJob` | Resume the execution of a JMS Router job.

Table 3-14, "JMS Router Settings" lists and describes the router and router job settings in the JMS Router MBean. The first column of the table lists the name of the setting in the JMS Router MBean. The settings that you make in the JMS Router MBean are persisted to the `jms.xml` file. The second column of the table lists the name of the corresponding elements in the `jms.xml` file.

Table 3-14 JMS Router Settings

MBean Setting | XML Entity | Description
--- | --- | ---
`jobName` Editable through the `addRouterJob` operation. | `<job-name>` Router job element | The name given to this router job. It must be unique for the OC4J instance for which it is configured.
`messageSource` Editable through the `addRouterJob` operation. | `<message-source>` Router job element | The JNDI location of the destination (topic or queue) to be used as the source of messages. If automatic destination wrapping is used, then the name may be of the form: `<JNDIsubcontext>/providerName` where `<JNDIsubcontext>` is the automatic destination wrapping JNDI subcontext as specified in `oc4j-connectors.xml`. For example, if automatic destination wrapping is used with the JMS Connector, a name would be of the form: `OracleASjms/Queues/jms/queue_name` or `OracleASjms/Topics/jms/topic_name`
`sourceConnectionFactory` Editable through the `addRouterJob` operation. | `<source-connection-factory>` Router job element | The JNDI location of the connection factory used to access the message source. For example, using the JMS Connector, a name might be `OracleASjms/MyCF` If the message source is a JMS Topic, this name must refer to a connection factory that supports both JMS Queues and Topics.
`messageTarget` Editable through the `addRouterJob` operation. | <`message-target>` Router job element | The JNDI location of the destination (topic or queue) to be used as the target for message propagation. If automatic destination wrapping is used, then the name may be of the form: `<JNDIsubcontext>/providerName` where `<JNDIsubcontext>` is the automatic destination wrapping JNDI subcontext as specified in `oc4j-connectors.xml`. For example, if automatic destination wrapping is used with the JMS Connector, a name would be of the form: `OracleASjms/Queues/jms/queue_name` or `OracleASjms/Topics/jms/topic_name`
`targetConnectionFactory` Editable through the `addRouterJob` operation. | `<target-connection-factory>` Router job element | The JNDI location of the connection factory used to access `messageTarget`. For example, using the JMS Connector, a name might be `OracleASjms/MyCF` If the message source is a JMS Topic, this name must refer to a connection factory that supports both JMS Queues and Topics.
`sourceLogQueue` Editable through the `addRouterJob` operation. | `<source-log-queue>` Router job element | The JNDI location of the queue to be used for JMS Router internal logging for the source messaging system. The log queue must be accessible through the connection factory indicated by `sourceConnectionFactory`. This parameter is optional when using OEMS JMS In-Memory or File-Based Destinations. In this case, if not specified, then the JMS Router uses the queue `OracleASRouter_LOGQ` If this queue does not exist, then the JMS Router will create it.
`targetLogQueue` Editable through the `addRouterJob` operation. | `<target-log-queue>` Router job element | The JNDI location of the queue to be used for JMS Router internal logging for the target messaging system. The log queue must be accessible through the connection factory indicated by `targetConnectionFactory`. This parameter is optional when using OEMS JMS In-Memory or File-Based Destinations. In this case, if not specified, then the JMS Router uses the queue `OracleASRouter_LOGQ` If this queue does not exist, then the JMS Router will create it.
`messageSelector` Editable through the `addRouterJob` operation. | `<message-selector>` Router job element | Optional. A message selector for selectively receiving messages from the `messageSource`. The default is `none`.
`subscriberName` Editable through the `addRouterJob` operation. | `<subscriber-name>` Router job element | Optional. The name for a durable subscriber to use if the `messageSource` is a topic. If the specified durable subscriber does not exist and the `messageSource` is a topic, then the JMS Router attempts to create it The default value is
    OracleASRouter_jobName
where jobName is the name of the Router job.
`exceptionQueue` Editable through the `addRouterJob` and `alterRouterJob` operations. | `<exception-queue>` Router job element | The JNDI location of a queue into which undeliverable messages are placed. The exception queue must be accessible from `sourceConnectionFactory`. This parameter need only be specified if useExceptionQueue is true. When useExceptionQueue is `true`, this parameter is optional when the message provider is OEMS JMS In-Memory or File-Based option. If not specified, then the JMS Router will use the OEMS JMS exception queue, `Oc4jJmsExceptionQueue`. This queue already exists, so does not need to be created separately. The default is `null` when using `alterRouterJob`.
`maxRetries` Editable through the `addRouterJob` and `alterRouterJob` operations. | `max-retries` Router job attribute | Optional. The number of times the JMS Router will attempt to deliver a message for this job before suspending execution of the job. The value must be an integer-valued string. If the string does not represent an integer, then it is ignored and the default is used. The default is `16` when using `addRouterJob`. The default is `null` when using `alterRouterJob`.
`pollingInterval` Editable through the `addRouterJob` and `alterRouterJob` operations. | `polling-interval` Router job attribute | Optional. If no message is present in the message source, then this parameter represents the minimum time in seconds to wait before checking the message source again. The value must be a string representing an integer. If the string does not represent an integer, then it is ignored and the default is used. The default is `5` when using `addRouterJob`. The default is `null` when using `alterRouterJob`.
`useExceptionQueue` Editable through the `addRouterJob` and `alterRouterJob` operations. | `use-exception-queue` Router job attribute | Optional. If the value is set to `true` and an exception queue is available, then undeliverable messages will be placed in it. Otherwise, no exception queue will be used. The default is `false` when using `addRouterJob`. The default is `null` when using `alterRouterJob`.
`pauseJob` Editable through the `addRouterJob` operation. | `pause-job` Router job attribute | Optional. If `true`, then the job is added in deactivated mode. To start the job, invoke `resumeJob`. If not `true`, then the job is created in activated mode. The default is `false`.
`batchSize` Editable through the `addRouterJob` and `alterRouterJob` operations. | `batch-size` Router job attribute | Optional. The number of messages to dequeue and enqueue in a single transaction. The default is `30` when using `addRouterJob`. The default is `null` when using `alterRouterJob`.
`removeSubscriber` Editable through the `removeRouterJob` operation. | `remove-subscriber` Router job attribute | If `true` and the router job used a durable subscriber, then the JMS Router attempts to remove that durable subscriber. If `false`, then no attempt is made to remove the durable subscriber. If the durable subscriber is not removed successfully by the JMS Router, then the user is responsible for its removal. The default is `true`.
`maxLocalConcurrency` Editable through the `configureRouter` operation. | `maxlocalconcurrency` Global JMS Router attribute | Optional. The maximum concurrency of dequeue operations possible. This argument places a limit on the number of threads that the JMS Router can use to dequeue messages at one time. A negative number indicates the JMS Router will enforce no limits on concurrency. The default behavior is to enforce no limits.

##### 3.6.3.5.1 JMS Router Configuration in jms.xml

The file `J2EE_HOME/config/jms.xml` is used to persist JMS Router jobs and global configuration.

In the `jms.xml` file, the JMS Router is configured in the `<jms-router>` element. A `<jms-router>` element consists of zero or more `<router-job>` elements. A JMS Router job is defined in the element `<router-job>`.

Table 3-14, "JMS Router Settings" lists and describes the JMS Router elements of the `jms.xml` file.

Minimal Example: JMS Router in jms.xml

This example illustrates a minimal configuration for a single JMS Router job that uses an OEMS JMS In-Memory queue as a source and an OEMS JMS In-Memory queue as target, utilizing the globally deployed JMS Connector instance `OracleASjms` for JMS objects.

    <?xml version="1.0"?>
    <jms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchema Location="http://www.oracle.com/technology/oracleas/schema/jms-server-10_1.xsd" schema-major-version="10" schema-minor-version="1">
      <!-- OracleAS JMS server configuration -- omitted for brevity  -->
      <jms-server>
         ...
      </jms-server>

      <!-- JMS Router configuration -->
      <jms-router max-local-concurrency="-1" >

         <!-- Minimal configuration for a JMS Router job.-->
         <router-job job-name="routerjob1">

            <!-- The name of a JMS Router destination -->
            <message-source>OracleASjms/Topics/jms/mySource</message-source>

            <!-- Connection factory for the message source. -->
            <source-connection-factory>OracleASjms/MyCF</source-connection-factory>

            <!-- The name of a JMS Router destination -->
            <message-target>OracleASjms/Queues/jms/myTarget</message-target>

            <!--Connection factory for the message target. -->
            <target-connection-factory>OracleASjms/MyCF</target-connection-factory>

         </router-job>
      </jms-router>

    </jms>

Syntax Example: JMS Router in jms.xml

This example illustrates the syntax of the JMS Router portion of `jms.xml` by defining a router job that provides values for all available attributes. It defines a configuration for a single JMS Router job that uses OEMS JMS In-Memory queue as source and OEMS JMS Database queue as target, utilizing the JMS Connector instance `OracleASjms` for the source JMS objects, and the JMS Connector instance `ojmsaq` for the target objects.

    <?xml version="1.0"?>
    <jms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchema Location="http://www.oracle.com/technology/oracleas/schema/jms-server-10_1.xsd" schema-major-version="10" schema-minor-version="1">
      <!-- OracleAS JMS server configuration -- omitted for brevity  -->
      <jms-server>
         ...
      </jms-server>

      <!-- JMS Router configuration -->
      <jms-router max-local-concurrency="-1" >

          <router-job
              job-name="routerjob1"
              max-retries="16"
              polling-interval="5"
              pause-job="false"
              use-exception-queue="true"
              batch-size="30"
          >
              <!-- The name of an JMS Router source destination -->
              <message-source>OracleASjms/Topics/jms/mySource</message-source>

              <!-- Connection factory for the message source. -->
              <source-connection-factory>OracleASjms/MyCF</source-connection-factory>

              <!-- A message selector used at the message source -->
              <message-selector>color='blue'</message-selector>

              <!--This is the default subscriber name for this job as written to this file by the JMS Router -->
              <subscriber-name>OracleASRouter_routerjob1</subscriber-name>

              <!--There is no need to specify the log queue for OracleAS JMS, but the default value will be written back to this file by the JMS Router -->
              <source-log-queue>OracleASjms/Queues/OracleASRouter_LOGQ</source-log-queue>

              <!-- An exception queue -->
              <exception-queue>OracleASjms/Queues/jms/myExQ</exception-queue>

              <!-- The name of an JMS Router target destination -->
              <message-target>ojmsaq/Queues/Queues/MyDBTarget</message-target>

              <!-Connection factory for the message target. -->
              <target-connection-factory>ojmsaq/CF</target-connection-factory>

              <!-- A log queue must be specified for all providers but OracleAS JMS. This queue must already exist  ->
              <target-log-queue>ojmsaq/Queues/Queues/MyJMSRouterLog</target-log-queue>

          </router-job>
      </jms-router>

    </jms>

### 3.6.4 Managing the Router

This section describes the JMS Router MBean operations for managing the JMS Router.

The JMS Router MBean enables you to:

- Start and stop individual JMS Router jobs

- Monitor router job status

- Monitor and query the JMS Router

Table 3-13, "JMS Router MBean Operations" lists and describes the JMS Router MBean operations.

Path to the JMS Router MBean:

OC4J:Home > Administration tab > Services > JMS Providers > Click the icon. > Select the appropriate tab. > Related Links: OracleASJMSRouter

#### 3.6.4.1 Router Logging

The JMS Router logs all significant events and error messages to the standard OC4J log file. The logger name is `oracle.j2ee.jms.router`.

#### 3.6.4.2 JMS Router Status Information

You can access JMS Router run-time status information using the `RouterJobsStatus` and `RouterGlobalStatus` attributes of the JMS Router MBean.

Table 3-15 JMS Router and Router Job Status

Statistic | Description
--- | ---
`NumberJobs` | The number of configured jobs
`RouterState` | A string representing the JMS Router state
`Retries` | Number of times the JMS Router has failed to deliver a message for this job
`ExceptionQMessages` | Number of messages moved to exception queue by this job
`LastErrorTime` | If this job is in an error state, the time last error occurred
`TargetQMessages` | Number of messages propagated to target queue by this job
`JobState` | A string representing the state of this job

#### 3.6.4.3 Error Handling

While processing a JMS Router job, the JMS Router may encounter various failures, such as an unreachable source or target destination or messaging operation failures. Based on the nature of the failures and the router job configuration, the JMS Router handles failures as follows:

If the JMS Router fails to enqueue a message to the target destination due to the content of the message and

- if no exception queue exists or the flag `useExceptionQueue` is set to `false` for the associated router job, then the JMS Router stops processing the router job.

- if an exception queue is provided for the job and the flag `useExceptionQueue` is set to `true` for the associated router job, then the JMS Router moves the message into the exception queue and the job continues processing subsequent messages.

When moving a message from the source destination to the exception queue, the JMS Router adds certain message properties to the original message to preserve error information. These messages are listed and described in Table 3-16, "Properties Added to Messages in Exception Queue".

Table 3-16 Properties Added to Messages in Exception Queue

JMS Property | Description
--- | ---
`oraMsgRouter_origMsgid` | ID of the source message
`oraMsgRouter_jobName` | Name of the router job
`oraMsgRouter_srcCF` | Name of the connection factory used for dequeue/enqueue
`oraMsgRouter_srcQName` | Name of the source queue from which the message was obtained
`oraMsgRouter_moveReason` | Reason the message was moved to exception queue
`oraMsgRouter_moveTime` | Time the message was moved to exception queue

If the failure is not due to the content of a message, the JMS Router will automatically retry the failing operation in the increasing intervals

    (2^n) * (pollingInterval),

with a maximum of 15 minutes, until it either succeeds or stops processing the router job when it reaches the configurable maximum number of retries specified in the `maxRetries` attribute, as described in Table 3-14, "JMS Router Settings" .

If the JMS Router stops processing a router job because the number of retries specified in the `maxRetries` setting has been reached, then users can call `resetJob` to reset the failure count to `0` to resume processing of the job.

The failure count of each job is stored in memory. Therefore, when the JMS Router restarts, the failure count of every job is reset to `0`.

#### 3.6.4.4 Pausing and Resuming a Job

A JMS Router job is in either `activated` or `deactivated` mode, as specified in the `pauseJob` setting, described in Table 3-14, "JMS Router Settings" .

The JMS Router does not process jobs that are in `deactivated` mode.

You can use the `pauseJob` operation in the JMS Router MBean to put a job in `deactivated` mode.

You can use the `resumeJob` operation in the JMS Router MBean to put a job in `activated` mode.

By default, jobs are created in `activated` mode.

#### 3.6.4.5 Running In a Clustered OC4J Environment

In a clustered OC4J environment, a JMS Router instance may run on each OC4J instance. These JMS Router instances are configured independently and run without knowledge of each other. A JMS Router job that is configured on an OC4J instance is processed by only the JMS Router instance running in that OC4J instance.

- Creating or managing a JMS Router job must be done using the JMS Router MBean or jms.xml file of a particular OC4J instance.

- All JMS connection factories and JMS destinations that are referenced by JMS Router jobs defined on an OC4J instance must be accessible from that OC4J instance

- If an OC4J instance is terminated, no jobs defined for the JMS Router instance running on the OC4J instance will be processed.

As a rule, different JMS Router jobs must not share a common source, i.e., a queue or a durable subscriber. Otherwise the JMS Router jobs may run into unrecoverable failures. In a clustered OC4J environment, this rule applies across all OC4J instances in the cluster.

- A JMS queue that is not an OEMS JMS In-Memory or File-Based distributed destination, can only be the source of one JMS Router job across the entire OC4J cluster.

- A JMS topic that is not an OEMS JMS In-Memory or File-Based distributed destination can be the source of multiple JMS Router jobs across the entire OC4J cluster. However, the associated durable subscriber names must be unique in the cluster. Specifically, if subscriber names of the JMS Router jobs are specified, the subscriber names must be different. If the subscriber names are not specified, the JMS Router job name must be unique across the cluster for jobs sharing the same topic as a source, since the JMS Router generates the durable subscriber names based on the JMS Router job names.

- Each copy of an OEMS JMS In-Memory or File-Based distributed destination on an OC4J instance in a cluster is treated by the JMS Router as a separate JMS destination. In order to route messages from an OEMS JMS In-Memory or File-Based distributed destination, a JMS Router job using the destination as the source must be defined on each OC4J instance.

#### 3.6.4.6 Routing with Remote Destinations

The JMS Router can route messages from one OC4J instance to another via OEMS JMS by using OEMS JMS remote connection factories. For more information, see Custom Topologies.

If a JMS Router job is defined using a connection factory for a remote OEMS JMS instance, any JMS destinations accessed using that connection factory must be defined on both the remote and local OC4J instances. If the source connection factory is remote, these JMS destinations include the message source, the JMS Router source log queue, and, optionally, an exception queue. If the target connection factory is remote, applicable JMS destinations include the message target, and the JMS Router target log queue.

The JMS Router log queue for OEMS JMS is named `OracleASRouter_LOGQ`. This queue is normally created automatically when a JMS Router job using OEMS JMS is first configured. However, when the message source or message target is remote, it may need to be created manually on the remote instance. Alternatively, a different persistent log queue may be created on the remote instance and specified when creating the JMS Router job.