5 Understanding Message Consumption

The following topics describe how to configure the JMS resource adapters ra.xml file to configure message-driven beans (MDBs) to asynchronously consume WebLogic JMS messages in a foreign application server as inbound messages:

Configuring MDBs to Consume Inbound Messages

Applications that require MDBs to asynchronously consumes messages from a WebLogic destination use the JMS resource adapters inbound implementation. The behavior of the MDBs is determined by configuring property values in the following files before deploying your application:

Configuring inbound-resourceadapter Properties in the ra.xml File

The following topics provide information about how to define inbound-resourceadapter properties for the inbound configuration in the ra.xml file:

Required activation-config Properties

You specify the required inbound-resourceadapter properties in the WebLogic JMS Resource-Adapter's ra.xml file, which is located in the WL_HOME\server\lib directory of your WebLogic Server installation.

The JMS properties you must specify include:

  • ConnectionFactory

  • destination

  • destinationType

You define the values for the ConnectionFactory, destination, and destinationType properties as activation-config properties in the ejb-jar.xml file. The JNDI names configured in the ejb-jar.xml must also map to the JNDI names that are assigned to the JMS resource adapter values of the connection-definition and adminobject elements.

See also the following topics:

Optional activation-config Properties

The JMS resource adapter supports a number of additional activation-config properties.

See Configuring activation-config Properties in the ejb-jar.xml File and JMS Resource Adapter Inbound Properties.

Example inbound-resourceadapter Configuration

The following code example shows an inbound-resourceadapter configuration:

. . .
<inbound-resourceadapter>
      <messageadapter>
        <messagelistener>
          <messagelistener-type>
            javax.jms.MessageListener
          </messagelistener-type>
          <activationspec>
            <activationspec-class>
              weblogic.jms.ra.ActivationSpecImpl
            </activationspec-class>
            <required-config-property>
              <config-property-name>ConnectionFactory</config-property-name>
            </required-config-property>
            <required-config-property>
              <config-property-name>Destination</config-property-name>
            </required-config-property>
            <required-config-property>
              <config-property-name>DestinationType</config-property-name>
            </required-config-property>
          </activationspec>
        </messagelistener>
      </messageadapter>
</inbound-resourceadapter>
. . .

Configuring activation-config Properties in the ejb-jar.xml File

The following topics provide information on how to configure activation-config properties in the ejb-jar.xml file:

The ejb-jar.xml File and Annotations

For elements in ejb-jar.xml, see the schema at http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd.

The ejb-jar.xml is optional as of EJB 3.0. You can use annotations to declare metadata in place of descriptor elements.

For information about how to program and implement EJB 3.2 compliant MDBs, see Using EJB 3.2 Compliant MDBs in Developing Message-Driven Beans for Oracle WebLogic Server.

Configuring Required activation-config Properties in the ejb-jar.xml File

You must configure an activation-config-property property for every required-config-property property in the inbound-resourceadapter of the ra.xml file.

The typical required JMS properties include:

  • ConnectionFactory—The JNDI location of a JMS Connector connection factory.

  • destination—The JNDI location of a JMS Connector destination.

  • destinationType—The type is one of the following:

    • javax.jms.Topic

    • javax.jms.Queue

    • javax.jms.Destination

In addition, if your MDB application uses optional activation-config properties, the foreign application server may require that these optional activation-config properties are defined in the ra.xml file as required-config-property elements.

For more information, see the documentation provided by the vendor of your application server.

Example Queue Configuration

The following example shows the activation-config properties for a queue configuration. In this example, the MDB that dequeues messages from a queue with the JNDI name wljmsra/queue uses a connection from the connection factory with the JNDI name wljmsra/xacf.

. . .
<activation-config-property>
  <activation-config-property-name>
    ConnectionFactory
  </activation-config-property-name>
  <activation-config-property-value>
    wljmsra/xacf
  </activation-config-property-value>
</activation-config-property>
<activation-config-property>
  <activation-config-property-name>
    Destination
  </activation-config-property-name>
  <activation-config-property-value>
    wljmsra/queue
  </activation-config-property-value>
</activation-config-property>
<activation-config-property>
  <activation-config-property-name>
    DestinationType
  </activation-config-property-name>
  <activation-config-property-value>
    javax.jms.Queue
  </activation-config-property-value>
</activation-config-property>
. . .
Example Topic Configuration

The following example shows the activation-config properties for a topic configuration. In this example, the MDB that dequeues messages from a topic with the JNDI name wljmsra/pdtopic1 uses a connection from the connection factory with the JNDI name wljmsra/txacf1.

. . .
<activation-config-property>
  <activation-config-property-name>
    ConnectionFactory
  </activation-config-property-name>
  <activation-config-property-value>
    wljmsra/txacf1
  </activation-config-property-value>
</activation-config-property>
<activation-config-property>
  <activation-config-property-name>
    Destination
  </activation-config-property-name>
  <activation-config-property-value>
    wljmsra/pdtopic1
  </activation-config-property-value>
</activation-config-property>
<activation-config-property>
  <activation-config-property-name>
    DestinationType
  </activation-config-property-name>
  <activation-config-property-value>
    javax.jms.Topic
  </activation-config-property-value>
</activation-config-property>
. . .

Configuring Optional activation-config Properties in the ejb-jar.xml File

Configure any additional properties needed to obtain the appropriate MDB behavior for your environment. For more information, see JMS Resource Adapter Inbound Properties.

Example ejb-jar.xml File with JMS Resource Adapter activation-config Properties

The following example shows an ejb-jar.xml file with JMS resource adapter activation-config properties:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee">
    <display-name>WebLogic RA Demo</display-name>
    <enterprise-beans>
        <message-driven>
            <display-name>My queue MDB</display-name>
            <ejb-name>queueMDB</ejb-name>
            <ejb-class>jms.ra.DisQueueMDB</ejb-class>
            <messaging-type>javax.jms.MessageListener</messaging-type>
            <transaction-type>Container</transaction-type>
            <activation-config>
                <activation-config-property>
                    <activation-config-property-name>
                            ConnectionFactory
                    </activation-config-property-name>
                    <activation-config-property-value>
                            java:sample/factory
                    </activation-config-property-value>
                </activation-config-property>
                <activation-config-property>
                    <activation-config-property-name>
                            Destination
                    </activation-config-property-name>
                    <activation-config-property-value>
                            java:sample/destination/queue
                    </activation-config-property-value>
                </activation-config-property>
                <activation-config-property>
                    <activation-config-property-name>
                            DestinationType
                    </activation-config-property-name>
                    <activation-config-property-value>
                            javax.jms.Queue
                    </activation-config-property-value>
                </activation-config-property>
                <activation-config-property>
                    <activation-config-property-name>UserName</activation-config-property-name>
                    <activation-config-property-value></activation-config-property-value>                </activation-config-property>
                <activation-config-property>
                    <activation-config-property-name>Password</activation-config-property-name>
                    <activation-config-property-value></activation-config-property-value>
                </activation-config-property>
                <activation-config-property>
                    <activation-config-property-name>ClientId</activation-config-property-name>
                    <activation-config-property-value>queueMDB</activation-config-property-value>
                </activation-config-property>
                <activation-config-property>
                    <activation-config-property-name>MessageSelector</activation-config-property-name>
                    <activation-config-property-value></activation-config-property-value>
                </activation-config-property>
            </activation-config>
        </message-driven>
       . . .           
      </message-driven>
    </enterprise-beans>
   . . .
</ejb-jar>

For additional ejb-xml.jar file examples, see the JMS resource adapter sample application example in your WebLogic Server distribution as described in JMS Resource Adapter Example.

Thread Management

The JMS resource adapter provides the following properties to manage the threads in destinations used by MDBs that consume inbound messages.

  • minListenerThreads—The minimum number of listener threads created for an individual physical destination.

  • maxTotalListenerThreads—The maximum number of listener threads available for a destination.

  • maxListenerThreads—The maximum number of listener threads created for an individual physical destination within a destination.

Setting the Maximum Threads for a Physical Destination

Note the following when configuring the maximum number of threads (maxListenerThreads) for a destination:

  • Queues—Using more than one thread may be useful in increasing the rate at which messages are consumed.

  • Topics—This value should always be 1. Each listener thread gets its own session and TopicSubscriber.

    • Durable subscribers—You may note have more than one subscriber with the same subscription name.

    • Nondurable subscribers—This value should always be 1. Creating more threads creates more subscribers, which results in excessive copies of each message to process.

Setting the Maximum Threads for a Distributed Destination

The maxTotalListenerThreads property allows you to limit or to provide additional processing threads for a distributed destination.

  • If the value of maxTotalListenerThreads is less than the number of physical destinations in the associated distributed destination, the JMS resource adapter uses a value equal to the number of physical destinations in the distributed destination and logs a warning message.

  • If the foreign application server cannot provide threads equal to or more than the number of physical destinations in the distributed destination, the JMS resource adapter logs a warning message.

  • The JMS resource adapter implements a fairness policy for allocating threads whereby any individual physical destination that is currently being serviced by less than maxListenerThreads, and that needs more threads, can reallocate threads from any other physical destination in the same distributed destination that has at least 2 more threads than it does. This fairness policy is independent of the foreign application server's WorkManager instance, which may not grant the JMS resource adapter's requests for additional maxTotalListenerThreads new threads.

    The process of reallocating threads from one destination to another takes some time, because both the determination of the thread deficiency and the transfer of the existing thread take place between the processing of messages (that is, between calls to onMessage). Since two threads are involved, the transfer process takes up to two onMessage processing times.

Using an Exception Queue

The JMS resource adapter allows you to configure an exception queue for inbound communications to handle poison messages from the inbound MDB queue. When the UseExceptionQueue property is enabled, messages that would otherwise be discarded are sent to the exception queue. Messages are normally sent to an exception queue when the maxDeliveryCount value is exceeded. For more information, see maxDeliveryCount.

Messages are processed to the exception queue using the following rules:

  • Messages are not set directly to the exception queue.

  • A new message of the same type is created.

    • The properties and body from the original message are copied to the new message.

      To prevent the original headers from being overwritten by the resource provider, each is copied to a GJRA_CopyOfJMS{Header} property. Because javax.jms.Destination is not a valid property type, each destination header is translated into a descriptive message. Note that JMSX* properties are not converted; for example, JMSXDeliveryCount.

      Note:

      If any part of the copy process fails, processing continue with the next rule. For Bytes/Map/Stream message types, this may result in only part of the message body being copied.

    • If the copy process is successful, the boolean property GJRA_CopySuccessful is added with the value true.

    • The string property GJRA_DeliveryFailureReason is added that contains the description explaining why the message was not delivered.

    • If the MDB onMessage method generates an exception immediately prior to the delivery failure, the string property GJRA_onMessageExceptions is added, which contains the exception information.

  • The copy of the original message is sent to the exception queue.

    Note:

    Only one attempt is made to send the copy of the original message to the exception queue. If this attempt fails, the message is discarded without being placed in the exception queue. For more information, see includeBodiesInExceptionQueue.

The connection factory used for the primary destination is also used for the exception queue. If the primary destination specified by the Destination property)is a topic, then the connection factory must support both queues and topics. For example, the <connectionfactory-interface> element must be either javax.jms.ConnectionFactory or javax.jms.XAConnectionFactory.

Setting User Name and Password Properties

The user name and password properties allow you to pass authentication parameters to the resource provider. When neither of these properties is set, then connections used for the MDB's inbound message handling are created using the no-argument version of the createConnection method. When one or both are set, the userNameand password properties are passed to the createConnection method as the user name and password arguments. If only one of the properties is not set, null is used to replace that property value in the createConnection argument list.)

Configuring Advanced WebLogic JMS Resources

The following topics provide information on how to configure advanced message processing for inbound messages:

The JMS Resource Adapter and Sharable Subscriptions

The JMS resource adapter uses a SHARABLE subscription sharing policy and UNRESTRICTED client ID policy when it processes inbound messages by overriding any configured connection factory settings. A subscriptionName must be provided for durable subscriptions because the JMS resource adapter's MDBs do not generate subscription names. Subscriptions are shared when they are durable or nondurable, as follows:

  • Durable—Consumers on the same distributed topic can share a durable subscriptions only if they have the same clientID, message selector, and subscriptionName.

  • Nondurable—Consumers on the same distributed topic can share a nondurable subscriptions only if they have the same clientID and messageSelector.

Always configure a clientId to ensure the MDB consumes incoming messages. For example:

. . .
<activation-config>
  <activation-config-property>
    
<activation-config-property-name>clientId</activation-config-property-name>
    <activation-config-property-value>myMDB</activation-config-property-value>
  </activation-config-property>
</activation-config> 
. . .

For more information, see Configure Shared Subscriptions in Administering JMS Resources for Oracle WebLogic Server.

Using Ordered Message Processing

If your application requires single-threaded processing of subscription messaging, then you must configure your application to use WebLogic JMS unit-of-ordering (UOO) processing.

For more information, see Using Message Unit-of-Order in Developing JMS Applications for Oracle WebLogic Server.

Design Strategies When Consuming from DistributedTopics

The following sections provide information on design strategies that can be used to develop high availability applications using distributed topics:

Replicated Versus Partitioned Distributed Topics

Replicated and partitioned distributed topics are supported for inbound message consumption as follows:

  • Replicated distributed topics—All physical topic members receive each message sent. When a message arrives at one of the physical topic members, a copy of the message is automatically and internally forwarded to the other members of the topic.

  • Partitioned distributed topics—The distributed topic member receiving the message is the only member that is aware of the message. The message is not forwarded to other members, and subscribers on other members do not get a copy of the message. Incoming messages can be load balanced among the distributed topic members using the JMS Affinity and Load Balance attributes. See Load Balancing Partitioned Distributed Topics in Administering JMS Resources for Oracle WebLogic Server.

One-Copy-Per-Application Design Strategy for Distributed Topics

One-Copy-Per-Application is the default design pattern available and has the following characteristics:

  • Each application as a whole (that is all instances of the application together) receives one copy of each message that is published to the distributed topic. That is each instance only receives a subset of the messages that are sent to the distributed topic.

  • An UNRESTRICTED client ID policy

  • An SHARABLE subscription sharing policy

  • Uses the same subscription name if the subscribers are durable

  • All consumers subscribe to the same topic instance (or member of a distributed topic)

Implementing One-Copy-Per-Application

To implement the One-Copy-Per-Application design strategy, you must specify the ProviderProperties property in your EJB with a value of TopicMessageDistributionMode=One-Copy-Per-Application in the activation-config element.

For more information, see Example One-Copy-Per-Application EJB Configuration.

Note:

If you do not specify TopicMessageDistributionMode=One-Copy-Per-Server, the JMS resource adapter defaults to TopicMessageDistributionMode=One-Copy-Per-Application to avoid message duplication.

Example One-Copy-Per-Application EJB Configuration

The following code snippet from an ejb-jar.xml file implements One-Copy-Per-Application message processing:

. . .
<mdb-resource-adapter>
  <resource-adapter-mid>wljmsra</resource-adapter-mid>
    <activation-config>
      <activation-config-property>
        <activation-config-property-name>ClientId</activation-config-property-name>
        <activation-config-property-value>RDT2MDB</activation-config-property-value>
      </activation-config-property>
      <activation-config-property>
        <activation-config-property-name>ProviderProperties</activation-config-property-name>
        <activation-config-property-value>TopicMessageDistributionMode=One-Copy-Per-Application</activation-config-property-value>
      </activation-config-property>
    </activation-config>
</mdb-resource-adapter>
 
<!-- Mapping a Queue admin-object to the Resource-Adapter name -->
  <resource-env-ref>
    <resource-env-ref-name>jms/ResultTopic</resource-env-ref-name>
    <jndi-name>wljmsra/rtopic1</jndi-name>
  </resource-env-ref>
 
<!-- Mapping a Connection Factory to the Resource-Adapter name -->
  <resource-ref>
    <res-ref-name>jms/ResultXACFFactory</res-ref-name>
    <jndi-name>wljmsra/xacf</jndi-name>
  </resource-ref>
. . .

One-Copy-Per-Server Design Strategy for Distributed Topics

One-Copy-Per-Server is a design pattern where each instance of an application gets one copy of each message that is published to the topic.

Implementing One-Copy-Per-Server

To implement the One-Copy-Per-Server design strategy, you must:

  • Specify the weblogic.jms.ra.providers.wl.ServerID property when starting the foreign server instance. For example: -Dweblogic.jms.ra.providers.wl.ServerID=aUniqueIdForTheServer

    In the preceding property specification, aUniqueIdForTheServer represents a unique identifier for your foreign server.

    For Oracle Glassfish, you can configure this property using the asadmin command, as follows:

    asadmin> create-jvm-options --user myUsername --password myPassword --host localhost --port 4848 -Dweblogic.jms.ra.providers.wl.ServerID="aUniqueIdForTheServer"

  • Specify the ProviderProperties property in your EJB with a value of TopicMessageDistributionMode=One-Copy-Per-Server in the activation-config element. For more information, see Example One-Copy-Per-Application EJB Configuration.

Example One-Copy-Per-Server

The following code snippet from an ejb-jar.xml file implements One-Copy-Per-Server message processing:

. . .
<mdb-resource-adapter>
  <resource-adapter-mid>wljmsra</resource-adapter-mid>
    <activation-config>
      <activation-config-property>
        <activation-config-property-name>ClientId</activation-config-property-name>
        <activation-config-property-value>RDTMDB</activation-config-property-value>
      </activation-config-property>
      <activation-config-property>
        <activation-config-property-name>ProviderProperties</activation-config-property-name>
        <activation-config-property-value>TopicMessageDistributionMode=One-Copy-Per-Server</activation-config-property-value>
      </activation-config-property>
    </activation-config>
</mdb-resource-adapter>
<!-- Mapping a Queue admin-object to the Resource-Adapter name -->
  <resource-env-ref>
    <resource-env-ref-name>jms/ResultTopic</resource-env-ref-name>
    <jndi-name>wljmsra/rtopic1</jndi-name>
  </resource-env-ref>
<!-- Mapping a Connection Factory to the Resource-Adapter name -->
  <resource-ref>
    <res-ref-name>jms/ResultXACFFactory</res-ref-name>
    <jndi-name>wljmsra/xacf</jndi-name>
  </resource-ref>
. . .

Consuming from Standalone (Nondistributed) Topics

On each foreign application server instance that hosts the MDB application, an MDB pool is created for the topic, whether the topic is running in the same cluster or in a different cluster. For an MDB cluster of N nodes, N MDB pools are created. Each MDB pool creates an individual subscription on the topic, and subscribers from different MDB pools do not share the same subscription.

For more information, see Implementing One-Copy-Per-Server.

Best Practices for Inbound Communication

Note the following tuning recommendations and best practices for configuring a JMS resource adapter for inbound communication:

  • Ensure that the JMS resource adapter allocates more threads than distributed destination members.

  • Always configure a clientID when using topics. The JMS resource adapter uses a SHARABLE subscription sharing policy when processing inbound messages, which requires a configured clientId for either durable or nondurable subscribers.

    If no clientID is set, then the MDB does not receive the message and the error condition logged in the foreign application server log.

    For more information, see The JMS Resource Adapter and Sharable Subscriptions.

  • For queues, increasing the value of maxListenerThreads to more than one thread may increase the rate at which messages are consumed.

  • The JMS resource adapter does not support sharable connections. If you use the <resource-ref> element in your application's deployment descriptor file (web.xml, and ejb-jar.xml) to identify the JMS connection factories that are looked up and used in that application, then you must set the <res-sharing-scope> child element to unsharable. The default value for this element is sharable.

    For example:

    . . .
    <resource-ref>
       <res-ref-name>jms/ReplyFactory</res-ref-name>
       <res-type>javax.jms.ConnectionFactory</res-type>
       <res-auth>Application</res-auth>
       <res-sharing-scope>unsharable</res-sharing-scope>
    </resource-ref>
    

    If your application uses @Resource injection, see http://docs.oracle.com/javaee/7/api/javax/annotation/Resource.html#shareable--.