Skip Headers
Oracle® Containers for J2EE Services Guide
10g Release 3 (10.1.3)
B14427-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
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:

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

This chapter discusses the following JMS tasks:

New JMS Features

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

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:

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:

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:

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.

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

Connection-factory and destination elements
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:

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.

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:

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:

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:

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

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:


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:

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.

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.

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:

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:

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:

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:

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:

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

Load balancing across two Oracle Application Servers.
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

Handling HTTP requests using a 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:

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:

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.