Oracle Message Broker Adminstration Guide Release 2.0.1.0 Part Number A65435-01 |
|
This chapter covers information about programming using the Oracle Message Broker and the JMS API. The following sections describe basic JMS programming using both JMS messaging domains, point-to-point (PTP), and publish/subscribe (Publish/Subscribe). Most client applications use only one of these JMS messaging domains.
This chapter covers the following:
There are four deployment options for an application, including:
Using each of these configuration and deployment options, an Oracle Message Broker application must perform the following tasks:
This chapter covers the methods you need to use to perform these tasks using an LDAP Directory and either Local Mode or Remote Mode (Non-Local Mode). Chapter 13, "Lightweight Configuration" covers the details for the application programming tasks using Lightweight Configuration.
Note: Using Local Mode or Remote (Non-Local Mode), the commands you use to start and stop the Oracle Message Broker differ. Refer to "Starting and Stopping the Oracle Message Broker" for information on starting and stopping the Oracle Message Broker. |
This section describes JMS programming using the Oracle Message Broker. Figure 3-1 shows the standard JMS client programming steps when using the LDAP Directory configuration option in Remote Mode. This section explains JMS programming for both Local Mode and Remote Mode.
The steps a JMS client program executes to access and use the Oracle Message Broker are as follows:
Refer to "Shutting Down" for PTP messaging or "Shutting Down (Publish/Subscribe)" for Publish/Subscribe messaging.
JMS clients obtain Oracle Message Broker administrative information from an LDAP Directory. Using JMS, clients find administrative objects by looking them up using JNDI. Oracle Message Broker clients follow this convention when the configuration mode uses the LDAP Directory. In this mode, the Oracle Message Broker uses the LDAP Directory to store administrative information, including the administrative objects for both PTP and Publish/Subscribe messaging.
The Oracle Message Broker also supports domain-specific methods for creating destinations dynamically. Dynamically created destinations do not use the LDAP Directory (see "Creating Destinations" for more details). Dynamic destinations are intended for use by advanced clients for specialized applications.
Using PTP messaging, client programs that send or receive messages need to obtain the following from the directory:
Similarly, using Publish/Subscribe messaging, client programs need to obtain the following from the directory:
Before you use JMS for PTP messaging, the administrator needs to create certain administrative objects (see Chapter 2 for information on creating administrative objects). After creating the administrative objects and starting the Oracle Message Broker, a client program obtains and uses the information stored in the directory to initialize a connection with the Oracle Message Broker.
A JMS client that sends or receives messages needs to create a queue connection factory. The client uses the queue connection factory to create a connection with the Oracle Message Broker.
To access the connection factory, the administrator creates a directory entry for the queue connection factory. The client uses the JMS API, and the connection factory that it obtains from the directory lookup to establish a connection with an active Oracle Message Broker. The Oracle Message Broker also supports a JMS extension for a connection factory that supports creating topic and queue connections (see "Universal Connections and Universal Sessions" for more information).
The following code shows the JNDI lookup for accessing a connection factory:
SimpleSession(DirContext initCtx, String cfDn) { QueueConnectionFactory queueConnectionFactory; try { queueConnectionFactory = (QueueConnectionFactory) initCtx.lookup(cfDn); if (queueConnectionFactory == null) { System.out.println("Lookup object returned null"); System.exit(-1); } }catch () { } }
As is the example above, to obtain a QueueConnectionFactory
instance, the client program uses a JNDI lookup on a connection factory entry in the LDAP Directory.
The Oracle Message Broker's JNDI support code obtains the IOR of a remote mode Oracle Message Broker process from an LDAP Server. The Oracle Message Broker client side runtime uses the IOR to communicate with the remote mode Oracle Message Broker using IIOP.
Note the following limitations when obtaining the QueueConnectionFactory
instance:
Obtains a connection factory instance using a JNDI lookup on a connection factory entry in the LDAP Directory. Oracle Message Broker's JNDI support code either starts an Oracle Message Broker within the Oracle Message Broker client process or obtains a handle to a previously started Oracle Message Broker within the Oracle Message Broker client process in the process before the lookup returns.
You can obtain instances of javax.jms.Queue using JNDI lookups on destination directory entries. The administrator creates the queue entries and queues that a client JMS program uses to specify, and that the Oracle Message Broker uses to determine where to store messages. A client program that needs to send or receive messages uses JNDI to locate the queue entry. The JNDI lookup returns a reference to an object that implements javax.jms.Queue.
The following code shows a queue lookup that creates a javax.jms.Queue
object:
queue = (Queue) initCtx.lookup(qDn);
Before you can use JMS for Publish/Subscribe messaging, the administrator needs to create certain administrative objects (see Chapter 2 for information on creating administrative objects). After creating the administrative objects and starting the Oracle Message Broker, a client program obtains and uses the information stored in the directory to initialize a connection with the Oracle Message Broker.
A JMS client program that publishes messages to a topic, or that subscribes to a topic, needs to create a topic connection factory. The client uses the topic connection factory to create a connection with the Oracle Message Broker.
To access the connection factory, the administrator creates a directory entry for the topic connection factory. The client uses the JMS API, and the connection factory that it obtains from the directory lookup to establish a connection with an active Oracle Message Broker. The Oracle Message Broker also supports a JMS extension for a connection factory that creates topic connections and queue connections (see "Universal Connections and Universal Sessions" for more information).
The following code shows the JNDI lookup for accessing a topic connection factory:
TopicConnectionFactory topicConnectionFactory; try { topicConnectionFactory = (TopicConnectionFactory)initCtx.lookup(cfDn); if (topicConnectionFactory == null) { System.out.println("Lookup object returned null"); System.exit(-1); } }catch () { } }
As is the example above, to obtain a TopicConnectionFactory
instance, the client program uses a JNDI lookup on a connection factory entry in the LDAP Directory.
The Oracle Message Broker's JNDI support code obtains the IOR of an Oracle Message Broker process from an LDAP server. The client program uses the Oracle Message Broker client-side runtime to interact with an Oracle Message Broker process using IIOP.
Note the following limitations when obtaining the TopicConnectionFactory
instance:
In Local Mode, the client program obtains a connection factory instance using a JNDI lookup on a connection factory entry in the LDAP Directory. Oracle Message Broker's JNDI support code either starts an Oracle Message Broker within the Oracle Message Broker client process or obtains a handle to a previously started Oracle Message Broker within the Oracle Message Broker client process in the process before the lookup returns.
You can obtain instances of javax.jms.Topic are using JNDI lookups on destination directory entries. The administrator creates the topic entries and queues that a client JMS program uses to specify and the Oracle Message Broker uses to determine where to store messages. A client program that needs to publish or subscribe to messages uses JNDI to locate the topic entry. The JNDI lookup returns a reference to an object that implements javax.jms.Topic.
The following code shows a topic lookup that creates a topic object:
topic = (Topic) initCtx.lookup(topicDn);
This section describes the programming steps required to send and receive messages using the JMS PTP methods. The following steps assume that the administrator has created the queue connection factory and one or more queues, and that these Oracle Message Broker administrative objects were obtained as described in "Accessing Objects in the Directory".
This section covers the following:
Figure 3-2 shows the path of messages for a simple point to point communication using a single queue.
Once you obtain a queue connection factory, use it to create a QueueConnection and use the start
method to establish communications with an active Oracle Message Broker. When you first create the QueueConnection, the connection is stopped.
The QueueConnection is an active connection to the JMS provider (Oracle Message Broker). A client uses the QueueConnection to create one or more QueueSessions for producing and consuming messages.
QueueConnection queueConnection = null; queueConnection = queueConnectionFactory.createQueueConnection(); queueConnection.start();
The JMS specification contains information that client programs should follow on the preferred use of the start
method. When the QueueConnection is created, it is in the stopped mode. In general, it is best to leave the connection in the stopped mode while its sessions are being created, and then use the start
method to start the stopped connection (for more information on conventions for using a session, see section 4.4.6 of the JMS specification).
After creating the QueueConnection, the client program needs to create a QueueSession. A session is single threaded, therefore concurrent operations are not allowed on a session. The session is used to create destinations for sending or receiving messages. A single connection can support multiple sessions, each maintaining its own state. The Oracle Message Broker supports a feature called Universal Sessions. Universal Sessions support both topic and queue sessions within a single session. See "Universal Connections and Universal Sessions" for more information on Universal Connections.
The following example shows how to create a session using the createQueueSession
method:
QueueSession queueSession = null; queueSession = queueConnection.createQueueSession(false, MercurySession.IMMEDIATE_ACKNOWLEDGE);
The first parameter to createQueueSession
indicates if the session is transacted. The parameter's value is either true or false.
The second parameter to createQueueSession
indicates the mode of acknowledging message receipt (for more information on message acknowledgment, see section 4.4.13 in the JMS specification and see "Message Listeners and Threads").
If the session is transacted, the first parameter to createQueueSession
is true, and the acknowledge mode parameter is ignored. If the session is not transacted, the first parameter to createQueueSession
is false, and the acknowledge mode parameter must be the following:
MercurySession.IMMEDIATE_ACKNOWLEDGE
Once a session is created, messages can be sent within the session by creating queue senders, and messages can be received by creating queue receivers. A destination must be specified when a queue receiver is created.
Use the QueueSession createSender
method to create a QueueSender.
QueueSender sender; sender = session.createSender(queue);
The createSender
method creates an object that can be used to send messages to a queue. The queue administrative object is obtained as described in "Accessing Objects for Point-to-Point Messaging".
Use the QueueSession method createReceiver
to create a QueueReceiver for receiving messages.
QueueReceiver receiver; receiver = session.createReceiver(queue);
The queue
parameter is the queue to receive messages from. The queue administrative object is obtained as described in "Accessing Objects for Point-to-Point Messaging".
Finally, the client program needs to create a message of the desired type and send it to a queue. The client program that is receiving messages also needs to create a message.
This example shows how to create and send a text message. The Oracle Message Broker and JMS support several message types in addition to a text message.
TextMessage message_out; message_out = session.createTextMessage(); message_out.setText("Data"); sender.send(message_out);
This example shows how to receive a text message.
A client can receive messages either synchronously or have the provider asynchronously deliver the messages as they arrive. For information on asynchronous delivery and the message listener interface, see the JMS specification, section 4.5.2.
The following code shows the use of the QueueReceiver.receive
method for
synchronous delivery:
TextMessage message_in; message_in = session.createTextMessage(); message_in = receiver.receive(); String inData = message_in.getText();
Client programs run in either Local Mode or Remote Mode (Non-Local Mode). A client program in either mode needs to shut down when it finishes. Refer to Chapter 5 for information on Local Mode and Remote Mode clients.
When a client is done with the Oracle Message Broker, it should call Mercury.shutdownClient()
. This shuts down any Oracle Message Brokers running in Local Mode, and the ORB, if remote Oracle Message Brokers have been accessed, and performs certain cleanup operations. Clients call this method as follows:
oracle.oas.mercury.Mercury.shutdownClient()
After the Oracle Message Broker is shut down, keep the following in mind:
Mercury.shutdownClient()
and then attempt to access a Remote Mode Oracle Message Broker by obtaining a connection factory.
This section describes the programming steps required to publish messages to a topic and subscribe to topics to receive messages using the JMS Publish/Subscribe methods. The following steps assume that the administrator has created the topic connection factory and one or more topics, and that these Oracle Message Broker administrative objects were obtained as described in "Accessing Objects in the Directory" .
This section covers the following:
Figure 3-3 shows the path of messages for a simple Publish/Subscribe model.
Once you obtain a topic connection factory, use it to create a TopicConnection and use the start
method to establish communications with the Oracle Message Broker. When you first create the TopicConnection, the connection is stopped.
The TopicConnection is an active connection to the provider. A client uses the TopicConnection to create one or more TopicSessions for producing and consuming messages.
TopicConnection topicConnection = null; topicConnection = topicConnectionFactory.createTopicConnection(); topicConnection.start();
The JMS specification contains information that client programs should follow on the preferred use of the start
method. When the TopicConnection is created, it is in the stopped mode. When a connection is stopped, consumers cannot receive messages. In general, it is best to leave the connection in the stopped mode while its sessions are being created, and then use the start
method to start the stopped connection (for more information on conventions for using a session, see section 4.4.6 of the JMS specification.)
After creating the TopicConnection, the client program needs to create a session. A session is single threaded, therefore concurrent operations are not allowed on a session. Subscribers and Publishers are created within the session. A single connection can support multiple sessions, each maintaining its own state (transactions, publishers, and subscribers).
The following example shows how to create a session using the TopicConnection's createTopicSession
method:
TopicSession topicSession = null; topicSession = topicConnection.createTopicSession(false, MercurySession.IMMEDIATE_ACKNOWLEDGE);
The first parameter to createTopicSession
indicates if the session is transacted. The parameter value is either true or false.
The second parameter to createTopicSession
indicates the mode of acknowledging message receipt (for more information on message acknowledgment, see section 4.4.13 in the JMS specification and see "Message Listeners and Threads").
If the session is transacted, the first parameter to createTopicSession
is true, and the acknowledge mode parameter is ignored. If the session is not transacted, the first parameter to createTopicSession
is false, and the acknowledge mode parameter must be the following:
MercurySession.IMMEDIATE_ACKNOWLEDGE
To publish messages to a topic, create a publisher within a session. To receive messages from a topic, create a subscriber within a session.
Use the TopicSession method createPublisher
to create a TopicPublisher.
TopicPublisher publisher; publisher = session.createPublisher(topic);
The topic
parameter is the topic to send messages to. The topic administrative object is obtained as described in "Accessing Objects for Point-to-Point Messaging".
Use the TopicSession method createSubscriber
to create a TopicSubscriber.
TopicSubscriber subscriber; subscriber = session.createSubscriber(topic);
The topic
parameter is the topic to subscribe to messages. The topic administrative object is obtained as described in "Accessing Objects for Point-to-Point Messaging".
Finally, the client program needs to create a message of the appropriate type and send it to a topic.
This example shows how to create and send a text message.
TextMessage message_out; message_out = session.createTextMessage(); message_out.setText("Data"); publisher.publish(message_out);
A client can receive messages either synchronously or have the provider asynchronously deliver the messages as they arrive. For information on asynchronous delivery and the message listener interface, see section 4.5.2 in the JMS specification.
The following code shows a synchronous delivery using the TopicSubscriber.receive
method:
TextMessage message_in; message_in = session.createTextMessage(); message_in = subscriber.receive(); String inData = message_in.getText();
Client programs run in either Local Mode or Remote Mode (Non-Local Mode). A client program in either mode needs to shut down when it finishes. Refer to Chapter 5 for information on Local Mode and Remote Mode clients.
When a client is done with the Oracle Message Broker, it needs to shut down. The procedure for shutting down is the same for PTP and Publish/Subscribe Messaging. See "Shutting Down" for more information.
This section lists important points to keep in mind when you are using JMS with message listeners.
Session.close()
When message listeners have been registered within a session, no listeners will be executed when Session.close
returns. The implication is that Session.close
blocks if a listener is executing the onMessage
method for that session.
MessageConsumer.setMessageListener
() only if the connection is stopped.
MessageConsumer.close()
method cannot be called after a listener has been registered within the session.
The following methods must be called by the thread executing the message listener if one has been registered (they cannot be called by any other thread after a message listener has been registered):
Session.rollack()
(can only be called by the listener)
Session.commit()
(can only be called by the listener)
Session.close
and MessageConsumer.setMessageListener
are the only methods that can be called in a session, or in the consumers, producers, and message listeners within that session once a message listener has been registered, if the caller is not executing in the thread that executes the message listeners.
MecurySession.IMMEDIATE_ACKNOWLEDGE
: the message will not be redelivered. The message is lost. In this mode, message delivery is at-most-once delivery.
Session.unsubscribe
. Subscriptions for non-durable subscribers are cancelled when the consumer is closed.
The Oracle Message Broker has a mechanism to detect JMS connections and sessions that have been closed implicitly (this means the JMS connection is closed by the finalizer rather than by a call to connection.close
or session.close
). When a JMS connection is closed, either implicitly or by calling connection.close
, there is no need to explicitly close the sessions, consumers, or producers that had been created within that JMS connection.
When message listeners have been registered within a session, no listeners will be executed when Session.close
returns. The implication is that Session.close
blocks if a listener is executing the onMessage
method for that session.
Connection.close
closes each session within that connection. Connection.close
blocks if a listener is executing within one of the connection's sessions. When Connection.close
returns, no message listeners will be executed for any listeners that had been set for the connection's sessions.
Oracle Message Broker objects other than JMS connections and sessions do not have a mechanism to detect consumers or producers that have been closed implicitly. When you are programming with Oracle Message Broker, it is important to explicitly close sessions, consumers, and producers using the corresponding close method when you are done with the object. When a session is closed, there is no need to explicitly close the consumers and producers that had been created within that session.
When a JMS connection is closed, explicitly or by the finalizer, Oracle Message Broker frees resources for the JMS connection, and the sessions, consumers, or producers within that JMS connection. Oracle Message Broker does not free resources for consumers or producers that have been garbage collected when the corresponding JMS connection or session has not been garbage collected. Oracle Message Broker detects client processes that have stopped running. If the Oracle Message Broker had allocated resource for the client it will cleanup the resources (rollback transactions, release Database Server connections). Note that the detection mechanism is not instantaneous, it takes some amount of time.
Several conditions may affect performance and available resources. For this section, use the following definitions:
The Oracle Message Broker uses a death detection thread that runs every 20 seconds to find leaked connections and leaked sessions. Leaked connections and leaked sessions will be detected within two intervals (40 seconds). Leaked connections and sessions, and the resources associated with them, are released when the leak is detected.
The death detection thread is run more frequently when any of the following occur:
The Oracle Message Broker sets the message priority after a client invokes the send or publish method on a message. This overwrites any value set by the client using a call to Message.setJMSPriority()
before the message is sent or published.
Oracle Message Broker sets the priority value for a message as follows:
MessageProducer.setPriority()
.
Use a call to Message.setJMSPriority()
to change the priority value for a message that has been received.
|
![]() Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
|