C Advanced Programming with Distributed Destinations Using the JMS Destination Availability Helper API

Learn how to design a distributed application or a container that offers high availability (HA), scalability, and flexibility when using JMS distributed destinations in a clustered environment.

Note:

Oracle recommends using message-driven beans (MDBs) where appropriate for applications that consume from distributed destinations. The MDB container manages consumers and recovery according to the destination type and configured distribution strategy, together with security, threading, pooling, lifecycle, and transaction integration. Applications that implement their own consumer management can use the Destination Availability Helper to respond to membership changes. The helper provides notifications; the application remains responsible for consumer creation, cleanup, and recovery.

Introduction

A distributed destination groups physical queues or topics behind a logical destination. Producer member selection and message distribution depend on whether the destination is a distributed queue, a partitioned distributed topic, or a replicated distributed topic. Consumer applications must provide the member coverage required by their delivery strategy and handle failures.

Distributed destination users that don't leverage MDBs may encounter problems with consumer applications. These include:

  • Failing to ensure that all DD members are serviced by consumers.

  • Unprocessed messages accumulating on DD members that have no consumers.

  • DD Consumers not automatically rebalancing in the event of a JMS server migration, WebLogic Server restart, or any other event that results in DD member changes.

To address these use cases, WebLogic Server provides the JMS Destination Availability Helper APIs and advanced topic features in Developing Advanced Pub/Sub Applications.

Controlling DD Producer Load Balancing

Before discussing consumer load balancing, it is helpful to first explore producer load balancing basics and best practices.

Basic JMS

A classic JMS application prepares to send messages as follows:

  1. Look up a connection factory and the destination, and create a Connection from the factory.

  2. Create a Session from the connection, then create a MessageProducer from the session.

  3. Send messages using the producer and the Destination object, either supplied when the producer is created or to the applicable send method.

The WebLogic Server hosting the JMS connection is the connection host. Connection-host selection depends on the connection factory's deployment, configuration, and server availability. The connection host routes operations to the destination's hosting service; it is not necessarily the destination host.

To use provider member selection for a distributed queue or partitioned distributed topic, look up the logical destination's JNDI name and use the returned Destination object. Use a physical member destination only when the application deliberately manages member selection.

Senders to Distributed Queues (DQs) and Partitioned Distributed Topics (PDTs)

When a producer sends to a logical distributed queue or partitioned distributed topic with Load Balancing Enabled, WebLogic selects eligible members using the configured load-balancing algorithm and applicable affinity and messaging rules. Server Affinity Enabled can favor eligible members on the connection host; it does not by itself define the complete selection order.

To allow selection without server affinity, use a custom connection factory with Server Affinity Enabled set to false and Load Balancing Enabled set to true. This does not guarantee round-robin selection across every active member. The destination's load-balancing algorithm, member availability, transactions, and Unit-of-Order requirements can affect selection.

Senders to Replicated Distributed Topics (RDTs)

A producer sending to a logical replicated distributed topic normally selects a member and continues using it. Unit-of-Order routing and failure handling can affect that selection. The RDT forwards published messages to its other members; delivery to subscriptions remains subject to normal JMS delivery and message-selection rules.

Server Affinity Enabled can influence the initial member selection. Set it to false on the connection factory if the application does not want that preference. Load Balancing Enabled does not cause an RDT producer to select a different member on each send.

Using the JMS Destination Availability Helper API

The following sections provide information on how to use the JMSDestinationAvailabilityHelper APIs:

Overview

For consumer APIs that support a logical distributed destination, creating a consumer selects a member. Existing consumers do not automatically redistribute themselves when new members become available. APIs that require a physical topic must instead use a member destination; see Considerations When Using Standard Shared Subscriptions.

The helper discovers destinations and reports membership changes for supported WebLogic distributed destinations. Register a listener using the destination's logical JNDI name to discover its members, including members that become available after application startup. A regular destination or third-party JMS destination provides only an initial successful-lookup notification, not continuing availability monitoring.

The application chooses which notified members need consumers for its delivery strategy. MDBs use destination discovery as part of their managed consumer lifecycle; applications using the helper directly must implement their own lifecycle and recovery.

General Flow

Applications that use the JMSDestinationAvailabilityHelper APIs should follow these general steps:

  1. Implement weblogic.jms.extensions.DestinationAvailabilityListener to handle the callbacks described in step 3.

  2. Register the destination's JNDI name and a listener with JMSDestinationAvailabilityHelper. The following complete helper method accepts an application-supplied JNDI environment and listener and returns the RegistrationHandle. An in-server application using its local naming context can supply null for the environment. For a remote naming service, supply the provider URL, initial context factory, and appropriate security configuration. Retain the handle until the registration is no longer needed.

    import java.util.Hashtable;
    import weblogic.jms.extensions.DestinationAvailabilityListener;
    import weblogic.jms.extensions.JMSDestinationAvailabilityHelper;
    import weblogic.jms.extensions.RegistrationHandle;
    
    public final class DestinationRegistration {
        public static RegistrationHandle register(
                Hashtable<String, Object> environment,
                String destinationJndiName,
                DestinationAvailabilityListener listener) {
            Hashtable<String, Object> properties = environment == null
                    ? null : new Hashtable<>(environment);
            return JMSDestinationAvailabilityHelper.getInstance()
                    .register(properties, destinationJndiName, listener);
        }
    }
  3. Handle the callbacks and coordinate shared state with application worker and recovery tasks. Do not assume that reusing one listener object for multiple registrations serializes its callbacks; use a separate listener per registration or appropriate synchronization.

    • onDestinationsAvailable(): The list contains newly available or newly rediscovered members, not a complete snapshot on every callback. Update the application's member state and arrange consumer creation for the required members. Availability can change before creation succeeds.

    • onDestinationsUnavailable(): For a logical distributed-destination registration, remove the reported members from application state, cancel their pending consumer-creation work, and close affected consumers. Other members remain in the application state.

    • onFailure(): Report discovery failures without repeatedly flooding the log. The helper retries discovery internally, but configuration or security errors can require administrator action. Helper retries do not recreate the application's JMS consumers.

  4. At application shutdown or undeployment, call unregister() on the RegistrationHandle, cancel application retry work, and close the JMS resources and JNDI contexts owned by the application. Unregistering the listener does not close application-created JMS resources.

Handling the weblogic.jms.extensions.DestinationDetail

Each callback entry implements weblogic.jms.extensions.DestinationDetail. Use getType() to identify its destination type and getJNDIName() to obtain the JNDI name represented by the entry.

For a member of a WebLogic logical distributed destination, getType() returns DESTINATION_TYPE_DD_QUEUE, DESTINATION_TYPE_REPLICATED_DT, or DESTINATION_TYPE_PARTITIONED_DT, and getJNDIName() identifies the member. Regular destinations use DESTINATION_TYPE_PHYSICAL_QUEUE or DESTINATION_TYPE_PHYSICAL_TOPIC. Third-party destinations use DESTINATION_TYPE_FOREIGN_QUEUE or DESTINATION_TYPE_FOREIGN_TOPIC. These constants are declared by DestinationDetail.

For distributed members, isLocalWLSServer() identifies membership on the WebLogic Server running the caller; isLocalCluster() identifies membership in that server's cluster. Cluster-local does not mean the same JVM. These flags do not establish local placement for regular or third-party destinations. Choose member coverage according to the application strategy before applying a locality optimization. See Best Practice for Local Server Consumers.

For the complete field and method contracts, see DestinationDetail in Java API Reference for Oracle WebLogic Server.

Best Practices for Consumer Containers

The following sections provide best practice guidelines for consumer containers:

When to Register and Unregister
  1. Register when the application starts or is deployed. Handle immediate registration errors as well as onFailure() callbacks. Temporary discovery failures need not prevent application startup, but expose configuration and security errors so that they can be corrected.

  2. Unregister at shutdown or undeployment, cancel application retry tasks, and close resources owned by the application.

URL Handling
  1. For an application running in WebLogic Server and using that server's local naming context, omit the provider URL. A standalone client or an application accessing a remote naming service must supply the appropriate provider URL and initial context factory.

  2. Use DestinationDetail.isLocalWLSServer() and isLocalCluster() to evaluate distributed-member locality. Do not infer that a remote naming URL is incorrect solely because a returned member is local; context selection also depends on the intended naming and security environment.

Failure Handling
  1. Log discovery failures and avoid repeating identical messages excessively. Distinguish temporary unavailability from an invalid JNDI name, provider URL, or security configuration. The helper retries discovery; administrator action may still be required.

  2. When the JMS connection fails, arrange cleanup and application-managed recovery outside the callback. Recreate the failed resources and restore the consumers required by the current member set. For other JMS exceptions, determine whether the operation can be retried or requires a configuration or application correction; do not treat every exception as a failed connection.

  3. Use delayed retries for transient failures and cancel them when the member is removed or the application stops. Coordinate retries with availability callbacks so that stale work does not recreate unwanted consumers.

JNDI Context Handling

Note:

Reuse a JNDI context only within a compatible provider and security scope, observing the provider's threading requirements. Use separate contexts when the application needs different domains or identities; see Understanding JMS Security.

Close contexts when they are no longer needed. For thread-based WebLogic security, create and close a context on the same thread and close nested contexts in reverse order so that the previous subject is restored. Passing a context to a different thread does not transfer the originating thread's subject.

Recreate a context when it is no longer usable. A failed lookup can instead indicate an incorrect name or unavailable binding; simply recreating the context does not correct every lookup failure.

JMS Connection Handling
  1. For application-owned JMS connections, register an ExceptionListener to observe connection failures. Container-managed JMS resources must follow the applicable component lifecycle and restrictions.

  2. Arrange recovery outside the exception callback using an execution mechanism allowed by the application's environment. Close failed application-owned resources and retry connection and consumer creation with a delay; coordinate this work with helper membership notifications.

  3. Cancel recovery work and close application-owned connections at shutdown or undeployment. Do not close resources owned by the container.

  4. Choose the number of connections and sessions according to concurrency, connection-host distribution, and resource usage. Additional connections may improve distribution but consume resources; measure the effect for the intended workload and provider.

Interoperability Guidelines

The JMSDestinationAvailabilityHelper in Java API Reference for Oracle WebLogic Server includes details about usage and behavior of the various methods available, including details about interoperability guidelines discussed in the following sections:

API Availability

JMSDestinationAvailabilityHelper is a WebLogic extension available to supported Java client and server environments that include this API. The legacy behavior described below explains compatibility handling; it does not establish that every older client or server version is supported with this release.

Foreign Contexts

The registration environment identifies the JNDI provider from which to resolve the destination. It can identify a supported WebLogic naming context or a compatible third-party context. Naming-provider availability alone does not establish JMS provider or release compatibility.

For foreign (non-WebLogic) contexts, the foreign JNDI vendor's classes must be in the current classpath and the Context.INITIAL_CONTEXT_FACTORY property must reference the foreign vendor JNDI context factory class name.

Destination Type Support

The helper can resolve WebLogic JMS and compatible third-party JMS destinations through JNDI. A Foreign JMS Server mapping is evaluated according to the destination to which it resolves: a WebLogic logical distributed destination can provide member notifications, whereas a third-party destination provides one initial availability notification. Do not use that initial notification as proof of continuing availability.

Unavailable Notifications

Unavailable notifications apply to member changes discovered through a WebLogic logical distributed-destination registration. Registrations for regular destinations, individual physical member destinations, and third-party destinations do not provide this monitoring. Such registrations provide one initial availability notification after successful resolution. Applications must still handle JMS operation failures.

Historical Behavior for Distributed Destinations Before WebLogic Server 9.0

The helper's compatibility handling distinguishes WebLogic distributed destinations before 9.0 from later distributed destinations. For a pre-9.0 destination, it reports one initial entry containing the logical JNDI name, with getType() returning DESTINATION_TYPE_PHYSICAL_QUEUE or DESTINATION_TYPE_PHYSICAL_TOPIC. It does not report individual member availability changes.

For later distributed destinations, a logical-destination registration can report individual members. These historical distinctions are not a statement of the client/server combinations supported by this release.

Historical Behavior for Distributed Topics Before WebLogic Server 10.3.4

The advanced WebLogic topic features used by the policy-based sharing patterns were introduced in WebLogic Server 10.3.4. Check DestinationDetail.isAdvancedTopicSupported() before applying those patterns to a discovered WebLogic topic. Do not infer support solely from a topic's JNDI name or treat third-party topic behavior as a WebLogic contract.

For historical replicated topics without these features, a non-durable consumer on one member can receive replicated publications, subject to normal delivery and selection rules; the all-member sharing patterns below must not be assumed to apply. Durable subscriptions require explicit physical-member selection and an appropriate identity and recovery design. Creating a durable consumer on a logical distributed-topic object is not supported.

Note:

For the policy configuration, see Configure an Unrestricted ClientID and Configure Shared Subscriptions in Administering JMS Resources for Oracle WebLogic Server.

DestinationDetail Fields

The information available in a DestinationDetail depends on the destination type and provider. See DestinationDetail in Java API Reference for Oracle WebLogic Server.

Security Considerations

The following sections provide information about implementing security using the Jakarta EE and WebLogic Server security models:

WebLogic Server Security Model

With thread-based JMS security, WebLogic uses the current thread's subject for subsequent JNDI and JMS operations. Creating a JMS resource under a subject does not permanently associate that subject with every later thread-based operation. Object-based security (OBS) instead associates a subject with the relevant JMS objects. See Understanding JMS Security.

Passing Credentials Between Threads

Passing a JNDI context or JMS object to another thread does not, by itself, establish the originating thread's subject on that thread. For thread-based security, run the operations under the appropriate subject. OBS has different identity-association rules; see Understanding JMS Security.

Using the Same Thread

For thread-based security, create the naming context, perform the related operations under the intended subject, and close the context on the same thread. If contexts are nested, close them in reverse creation order. Use explicit subject selection when operations for different identities are interleaved.

Pass as Anonymous User

Use an anonymous subject only when the intended JNDI and JMS operations are authorized for anonymous users. Anonymous access is not a general solution for cross-domain security. Configure the appropriate identity and domain security for the operation; see Managing Cross-Domain Security.

Cache and Reuse a Subject from the Initial Context

The following helper captures the current subject when it is constructed. Construct it while the intended subject is active, then use run() to execute an operation under that subject on the calling thread, including an application worker thread. It does not create an anonymous subject or extract a subject from a context passed from another thread. PrivilegedActionException is propagated to the caller for handling.

import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.security.auth.Subject;
import weblogic.security.Security;

public final class CapturedSubject {
    private final Subject subject;

    public CapturedSubject() {
        subject = Security.getCurrentSubject();
    }

    public Object run(PrivilegedExceptionAction<?> action)
            throws PrivilegedActionException {
        return Security.runAs(subject, action);
    }
}
Managing Cross-Domain Security

When using the JMSDestinationAvailabilityHelper API in communication between different WebLogic domains, see Cross-Domain Security Guidelines.

Authentication of Users

Authentication establishes the user's identity. Authorization separately determines whether that identity can perform the requested JNDI and JMS operations. The following sections describe where credentials are supplied and which operations use the resulting subject.

Specifying Credentials for a JNDI Context

Supply the appropriate credentials when creating a naming context that requires authentication. For the thread-based WebLogic context, the resulting subject applies to subsequent operations on that thread. An in-server local context created without a provider URL or credentials uses the existing thread identity. Closing the context on its creating thread restores the preceding subject; close nested contexts in reverse order.

These thread-based rules do not describe OBS context behavior. See Understanding JMS Security for OBS defaults, explicit JMS credentials, and subject selection across domains.

Specifying Credentials for a JMS Connection

The username and password supplied to createConnection() or createContext() are used to authenticate the connection request. With thread-based WebLogic JMS security, subsequent operations use the current thread's subject; supplying connection credentials does not set that thread's identity for later operations. With OBS, explicit JMS credentials can select the subject associated with the JMS objects. See Understanding JMS Security.

Using Credentials of a Foreign JMS Server JNDI Context

Configure the Foreign JMS Server's naming environment for access to the remote JNDI provider. Specify the naming principal through the appropriate JNDI property and the naming credential through JNDI Properties Credential. These naming credentials are distinct from the username and password configured on a Foreign Connection Factory mapping.

Using Credentials of a Foreign JMS Server Connection

The username and password on a Foreign Connection Factory mapping are used by supported WebLogic integrations, including MDB connections and managed resource-reference access. A direct lookup of the underlying connection factory does not automatically supply these credentials to an application's createConnection() or createContext() call. See Enhanced Support for Using WebLogic JMS with EJBs and Servlets.

Securing Destinations

Use JMS resource security policies to authorize operations on destinations. See Java Messaging Service (JMS) Resources in Securing Resources Using Roles and Policies for Oracle WebLogic Server.

Securing Wire Data

Use appropriately configured TLS connections when JMS data must be protected in transit. See Configuring SSL in Administering Security for Oracle WebLogic Server.

Transaction Considerations

JTA transaction association is thread-based. WebLogic JMS operations can enlist automatically in the current WebLogic JTA transaction when the connection factory and resource integration support that participation. Do not assume that the presence of a transaction alone makes every JMS resource transactional. See Automatically Enlisting Transactions.

For a third-party JMS provider, use a supported transaction integration, such as an appropriately configured managed resource reference with an XA-capable provider. A standalone application must not assume that WebLogic JMS automatically enlists with an arbitrary third-party transaction manager. See FAQs: Integrating Remote JMS Providers.

A native locally transacted JMS session has its own commit and rollback boundary; it is not the same as a container-managed session participating in JTA. An XA-capable factory does not prevent the applicable native API from creating a local transaction. Follow the programming model and transaction rules described in Using Transactions with WebLogic JMS.

Keep transaction work on the associated thread unless the application deliberately uses a supported transaction suspend/resume mechanism. Do not assume that handing a JMS resource to a worker thread transfers the transaction.

Strategies for Uniform Distributed Queue Consumers

A UDQ consumer application can run inside WebLogic Server or as a standalone client. Server-side applications may run with the destination services or access them remotely.

Note:

Oracle recommends MDBs where appropriate so that the container manages consumer lifecycle and recovery.

The following guidance applies to applications that manage their own consumers.

General Strategies

Design the application's consumer population to cover the UDQ members that can hold messages for its workload. Register the logical UDQ JNDI name with JMSDestinationAvailabilityHelper. Each registration reports newly available members and subsequent removals; keep an application member set rather than treating every notification as a full snapshot.

One straightforward strategy is for each application instance to create consumers on every available member. Another is to distribute member coverage among instances. For each newly available member assigned to an instance, create the required consumer or consumers and arrange delayed recovery if creation fails. For each unavailable member, remove its state, cancel pending creation work, and close its consumers.

Consumers on a queue compete for eligible messages; member coverage does not reserve every message for this application when other consumers exist. If the design relies on configured queue forwarding, account for its routing, ordering, and availability behavior. See Best Practice for Local Server Consumers.

Best Practice for Local Server Consumers

Consuming from members on the application's WebLogic Server can reduce network traffic when the JMS connection host is also local. Use DestinationDetail.isLocalWLSServer() to identify those members. isLocalCluster() identifies the same cluster and does not establish same-server placement.

Restrict consumption to local members only when application instances collectively cover all required members, including after service migration or membership changes. Otherwise provide remote consumers or another appropriate coverage strategy. Local-only consumption can also leave processing capacity unevenly used when member backlogs differ; evaluate distribution and recovery for the workload.

Strategies for Subscribers on Uniform Distributed Topics

Note:

Oracle recommends using MDBs to implement advanced message distribution modes using replicated and partitioned distributed topics. For detailed information about advanced publish/subscribe application design using MDBs, see Developing Advanced Pub/Sub Applications and Configuring and Deploying MDBs Using Distributed Topics in Developing Message-Driven Beans for Oracle WebLogic Server.

The following recipes describe WebLogic policy-based subscription sharing through traditional subscriber APIs. Configure Client ID Policy as Unrestricted and Subscription Sharing Policy as Sharable when using those recipes, and create subscribers on physical member destinations discovered through JMSDestinationAvailabilityHelper. These are not universal prerequisites for the standard named shared-subscription APIs. See Shared Subscriptions and Client ID Policy and Considerations When Using Standard Shared Subscriptions.

A replicated distributed topic (RDT) forwards publications among its members. A partitioned distributed topic (PDT) does not replicate each publication to the other members; subscribers must cover the appropriate members to receive the application's publications. Normal message selection, delivery, expiration, and durable-subscription retention rules still apply.

Choose the one-copy-per-instance or one-copy-per-application strategy according to the required application behavior. The following sections describe member coverage and subscription identity for each strategy.

See Configuring Partitioned Distributed Topics in Administering JMS Resources for Oracle WebLogic Server.

One Copy Per Instance

With the one-copy-per-instance strategy, each application instance has its own subscription and receives its own copy of messages published to the topic, subject to normal JMS delivery and message-selection rules. Use the following policy-based recipe when each instance must process the messages independently.

General Pattern Design Strategy for One Copy Per Instance

For the all-member policy-based strategy, each application instance performs the following steps.

  1. Choose a client ID unique to the application instance, such as an application base ID plus a stable instance identifier. Use that same instance identity on its connections. For durable consumption, choose a stable subscription name and reuse it when reopening that instance's subscriptions.
  2. Create the connections and sessions. Configure Client ID Policy as Unrestricted and Subscription Sharing Policy as Sharable before creating subscribers. Within an instance, consumers intended to share a physical subscription must use matching subscription details; different instances must not accidentally share the same subscription identity.
  3. Register the logical distributed-topic JNDI name with JMSDestinationAvailabilityHelper and maintain the reported member set. Arrange application-owned connection failure handling and delayed recovery outside callbacks.
  4. Create subscribers for this instance on every available member. On a PDT, this coverage is required because publications are partitioned among members. A matching subscription identity on another member still identifies a separate physical subscription.
  5. For an RDT in this all-member strategy, exclude forwarded replicas. With no application selector, use NOT JMS_WL_DDForwarded. With an application selector, use (NOT JMS_WL_DDForwarded) AND (<application-selector>), replacing the placeholder with the complete selector expression. Preserve the parentheses around the entire application selector. Do not apply this filter to a strategy that depends on receiving replicated copies from one RDT member.
  6. When a member becomes unavailable, cancel its pending creation work and close its consumers. Recreate the required consumers when it is reported available again. Preserve durable identity when reopening retained subscriptions; do not unsubscribe as routine failure cleanup.
  7. At shutdown, unregister, cancel recovery tasks, and close application-owned resources. Manage durable-subscription deletion separately from consumer closure.
Best Practice for Local Server Consumers using One Copy Per Instance

For a PDT, each application instance that needs its own copy of all publications must cover every member, including remote members. Limiting that instance to members on its own server does not implement the one-copy-per-instance strategy. Follow General Pattern Design Strategy for One Copy Per Instance.

For non-durable consumption from an RDT, an alternative is to select one available member per application instance and receive that member's replicated publications. A local member may reduce network traffic. Do not apply NOT JMS_WL_DDForwarded in this one-member design, because it relies on forwarded copies. Handle member failure and selection of a replacement; a non-durable subscription does not retain messages while it is absent.

For durable consumption, retain the all-member strategy unless the application explicitly manages durable member identity, retained backlogs, and recovery. Creating a subscription on a different member does not transfer the old member's durable backlog.

Use DestinationDetail.isLocalWLSServer() when evaluating locality. DestinationDetail is the top-level weblogic.jms.extensions interface. Locality is an optimization only after the required delivery and recovery behavior has been established.

One Copy Per Application

With the one-copy-per-application strategy, application instances share subscriptions so that each publication is delivered to the application as a whole rather than separately to every instance, subject to normal JMS delivery and message-selection rules. Messages can be distributed among instances so that they share the processing work. Failures and redelivery can still result in repeated processing.

The following sections describe the policy-based design and its local-consumer optimization.

General Pattern Design Strategy for One Copy Per Application

For policy-based one-copy-per-application consumption, coordinate the application instances as follows.

  1. Choose one application client ID to use on all participating connections. For durable consumption, choose one common application subscription name; do not derive a different name for each application instance. Reuse the same identity when reopening the application's subscriptions.
  2. Configure Client ID Policy as Unrestricted and Subscription Sharing Policy as Sharable before creating subscribers. For policy-based non-durable sharing, match the physical topic, client ID and policy, selector, and noLocal setting. For durable sharing, use the common client ID and subscription name with compatible subscription settings.
  3. Register the logical distributed-topic JNDI name with JMSDestinationAvailabilityHelper. Maintain member state and arrange application-owned connection failure handling and delayed recovery outside callbacks.
  4. Ensure that the application instances collectively provide subscribers on every available member required by the strategy. Multiple instances may share the same physical member's subscription. Matching keys on different members identify separate physical subscriptions; a common client ID does not merge them across the distributed topic.
  5. For an RDT, use NOT JMS_WL_DDForwarded to exclude replicated copies. If an application selector is also needed, use (NOT JMS_WL_DDForwarded) AND (<application-selector>), substituting the complete selector and retaining its parentheses. For a PDT, consume each member's publications without that RDT replica filter.
  6. For each unavailable member, cancel pending creation work and close affected consumers. Restore required coverage when the member becomes available again. Preserve durable identity and retained subscriptions during ordinary recovery.
  7. At shutdown, unregister and cancel retry work, then close application-owned resources. Coordinate durable-subscription deletion separately; closing a consumer does not delete its durable subscription.
Best Practice for Local Server Consumers Using One Copy Per Application

The application can limit each instance to local members when its instances collectively cover every required distributed-topic member, including after service migration or membership changes. Use DestinationDetail.isLocalWLSServer() to identify a member on the calling instance's WebLogic Server. Same-cluster placement alone does not provide same-server locality or complete coverage.

Retain the common application subscription identity and the other requirements in General Pattern Design Strategy for One Copy Per Application. For an RDT, retain the NOT JMS_WL_DDForwarded selector so that the application consumes the original publication at its originating member rather than additional replicated copies. For a PDT, collectively cover the members containing the partitioned publications.

If a member has no local application instance, provide a remote consumer or another recovery arrangement that restores the required coverage. Evaluate workload distribution as well as locality; local-only consumption is an optimization, not a replacement for member and failure handling.