Skip to content
carterpage edited this page Apr 19, 2012 · 2 revisions

JMS 1.1 Boil-down

This is a boil-down of the JMS 1.1 spec to all the actionable requirements contained. This is to be used as a starting reference point for the Nevado JMS provider.

1 Introduction

1.4.4 JTA

A JMS client may use JTA to delimit distributed transactions; however this is a function of the transaction environment the client is running in. It is not a feature of JMS.

A JMS provider can optionally support distributed transactions via JTA.

[Defer to post-1.0]

[Per section 2.8 (multithreading) the Session object is the class that JMS uses to support transactions.]

2 Architecture

2.6.1 Developing a JMS Client

A typical JMS client executes the following JMS setup procedure:

  • Use JNDI to find a ConnectionFactory object
  • Use JNDI to find one or more Destination objects
  • Use the ConnectionFactory to create a JMS Connection with message delivery inhibited
  • Use the Connection to create one or more JMS Sessions
  • Use a Session and the Destination to create the MessageProducers and MessageConsumers needed
  • Tell the Connection to start delivery of messages

2.8 Multi-threading

JMS requires that the following objects support concurrent use:

  • Destination
  • ConnectionFactory
  • Connection

[Unit tests should test concurrent access.]

It does not require the following to support concurrency:

  • Session
  • MessageProducer
  • MessageConsumer

3 JMS Message Model

3.2 Goals

The JMS message model has the following goals:

  • Provide a single, unified message API
  • Provide an API suitable for creating messages that match the format used by existing, non-JMS applications
  • Support the development of heterogenous applications that span operating systems, machine architectures, and computer languages
  • Support messages containing Java objects [Covered by ObjectMessageTest.*]
  • Support messages containing XML [Covered by TextMessageTest.testXml()]

3.3 JMS Messages

JMS messages are composed of the header, properties, and body.

Headers are predefined fields.

Properties are basically optional headers:

  • Application-specific properties
  • Standard properties
  • Provider-specific properties

[We should create a notion of properties that handles and validates these types.]

3.4.1 JMSDestination [Covered by JMSDestinationTest.testAssign]

3.4.2 JMSDeliveryMode [Covered by JMSDeliveryModeTest.testAssign]

3.4.3 JMSMessageID [Covered]

When a message is sent, JMSMessageID is ignored. When the send method returns, the field contains a provider-assigned value. [JMSMessageIDTest.testAssign]

A JMSMessageID is a String value which should function as a unique key for identifying messages in a historical repository. The exact scope of uniqueness is provider defined. It should at least cover all messages for a specific installation of a provider where an installation is some connected set of message routers. [Uses SQS message ID: "considered unique across all AWS accounts for an extended period of time" http://aws.amazon.com/articles/Amazon-SQS/1343#05]

All JMSMessageID values must start with 'ID:'. Uniqueness of message ID values across different providers is not required. [JMSMessageIDTest.testAssign]

JMS MessageProducer provides a hint to disable message ID. ... If the JMS provider accepts this hint, these messages must have the message ID set ot null; if the provider ignores the hint, the message ID must be set to its normal unique value." [JMSMessageIDTest.testDisable]

3.4.4 JMSTimestamp [Covered]

The JMSTimestamp header field contains the time a message was handed off to the provider to be sent. (Not the time it was actually transmitted.) The value should be the number of milliseconds since midnight GMT, Jan 1, 1970. [JMSTimestampTest.testAssign]

JMS MessageProducer may provides a hint to disable timestamp, in which case it is set to 0. [JMSTimestampTest.testDisable]

3.4.5 JMSCorrelationID [ClientJMSHeadersTest.testAssign]

3.4.6 JMSReplyTo [ClientJMSHeadersTest.testAssign]

3.4.7 JMSRedelivered

A provider must set the JMSRedelivered message header field of a message to true whenever it is redelivering a message.

This field is left unassigned by the sending method.

3.4.8 JMSType [ClientJMSHeadersTest.testAssign]

The JMSType header field contains a message type identifier supplied by a client when a message is sent.

JMS does not define a standard message definition repository, nor does it define a naming policy for the definitions it contains.

To insure portability, JMS clients should use symbolic values for JMSType that can be configured at installation time to the values defined in the current provider's message repository. If string literals are used, they may not be valid type names for some JMS providers.

[Need to research a little more how other providers handle this, and probably follow their lead.]

3.4.9 JMSExpiration [Covered]

When a message is sent, its expiration time is calculated as the sum of the TTL specified on the send method and the current GMT. [JMSExpirationTest.testSetExpiration]

If the TTL is zero, expiration is set to zero to indicate no expiration. [JMSExpirationTest.testControl]

When GMT is later than an undelivered message's expiration time, the message should be destroyed. Not notification is necessary. [JMSExpirationTest.testExpire]

Clients should not receive messages that have expired; however, JMS does not guarantee that this will not happen.

3.4.10 JMSPriority [Covered, except no message expediting]

After a message is set, the JMSPriority should reflect the value set in the send method. [JMSPriorityTest.testAssign]

Implementation of queue priority will probably be deferred to a later version.

Can contain a value 0-9. 0-4 is considered normal priority, and 5-9 is expedited priority.

JMS does not require that a provider strictly implement priority ordering of messages; however it should do its best to deliver expedited messages ahead of normal messages.

3.4.11 How Message Headers are Set [No cover needed]

Send Method:

  • JMSDestination
  • JMSDeliveryMode
  • JMSExpiration
  • JMSPriority
  • JMSMessageID
  • JMSTimestamp

Client:

  • JMSCorrelationID
  • JMSReplyTo
  • JMSType

Provider:

  • JMSRedelivered

3.4.12 Overriding Headers [Covered in JMSHeaderOverrideTest.testOverride]

[Defer to post-1.0]

JMS permits an administrator to configure JMS to override the client-specified values for JMSDeliveryMode, JMSExpiration, and JMSPriority.

JMS does not define how the override should happen, nor does it require this option.

3.5 Message Properties

Message properties are useful as optional headers and as criteria for message selectors (Sec 3.8).

Property values can be the following. (Valid input types are in parentheses. All should take String and its own type too.):

  • boolean
  • byte
  • short (byte)
  • int (byte, short)
  • long (byte, short, int)
  • float
  • double (float)
  • String (all of the above)

If there is an attempt to set a field that doesn't match type (ie setting a float with an int) should throw a MessageFormatException.

Property values are set prior to sending a message. If a client attempts to set properties after receiving the message, a MessageNotWritableException is thrown. However, if the property values are cleared, the read-only state should be cleared, making these writable again.

The order of priorities is not defined. (Sec. 3.5.6)

3.5.5 Property Values as Objects

The setObjectProperty method accepts values of the following types:

  • Boolean
  • Byte
  • Short
  • Integer
  • Long
  • Float
  • Double
  • String

An attempt to use any other class must throw a MessageFormatException.

The getObjectProperty method only returns values of the same types above or null. A null value is returned if a property does not exist. (Reiterated in Sec. 3.5.8).

3.5.7 Clearing Properties

clearProperties should delete all properties. This does not effect the body.

JMS does not provide a way to remove individual properties entry once it has been added to a message. Seems to be all or none.

3.5.9 JMS Defined Properties

JMS reserves the 'JMSX' prefix for JMS-defined properties.

Support for these properties is optional. ConnectionMetaData.getJMSXPropertyNames() returns the names of the JMSX properties supported by a connection.

Task: Ensure that a user cannot set the following JMSXUserID, JMSXAppID, JMSXDeliveryCount, JMSXProducerTXID, JMSXConsumerTXID, JMSXRcvTimestamp, JMSXState.

Clients are allowed to set JMSXGroupID and JMSXGroupSeq

3.5.10 Provider Properties

JMS reserves teh "JMS_" prefix for provider-specific properties.

Task: While we don't have any plans for provider specific properties, we should prevent a client from setting any properties that would collide with the name space.

The prefix for this should be JMS_nevado.

These properties if used are for provider-native clients. They should not be used for JMS-to-JMS messaging.

3.10 Modifying a Received Message

When a message is received, its header field values can be changed; however its properties and body are read-only.

A consumer can modify a received message body after calling clearBody, or the properties after calling clearProperties.

It's not 100% clear if calling clearBody makes properties writable (or vice-versa). That would make it a little simpler, since there would only need to be one readOnly flag for the message, but this may be contradicted by Sec. 3.5.7 which seems to imply that clearing properties has no impact on body (and probably vice-versa).

3.8 - Message Selection

[Defer for post-1.0]

3.11 Message Body

JMS has five forms of body:

  • StreamMessage (a list of primitive values)
  • MapMessage (String -> primitive, undefined order)
  • TextMessage (String)
  • ObjectMessage (Serializable object)
  • BytesMessage (typically not used, a list of bytes)

clearBody resets the value to the initial empty value as set by the type's create method. Clearing a body does not clear properties.

If an attempt is made to change the body after it has been delivered, MessageNotWritableException must be thrown. If it is subsequently cleared, it can be written to once again.

3.11.3 - StreamMessage and MapMessage conversions

The following types can be set with the inputs in parentheses (and one's own type):

  • boolean (String)
  • byte (String)
  • short (byte, String)
  • char
  • int (byte, short, String)
  • long (byte, short, int, String)
  • float (String)
  • double (float, String)
  • String (all the above -- i.e. not byte[])
  • byte[]

Cases that don't match the above conversions must throw MessageFormatException.

String to numeric conversions should basically call the appropriate valueOf() message. In cases of setting a numeric with an invalid string representation a NumberFormatException should be thrown.

String to boolean conversion must be implemented via Boolean.valueOf(String)

If a read method of StreamMessage or ByteMessage throws a MessageFormatException or NumberFormatException, the current position of the read pointer must not be incremented. A subsequent read must be capable of recovering from the exception by rereading the data as a different type.

When passed between clients, a message must always retain its full form. For instance, a message sent as MapMessage must not arrive at a JMS client as a BytesMessage. [MapMessageTest.testMapMessage,StreamMessageTest.testStreamMessage]

If a provider receives a message created by a native (non-JMS?) client, the provider should do its best to transform it into the best JMS message type. For instance, if it is a native stream message, it should be transformed into a StreamMessage. If this is not possible, the provider is always able to transform it into a BytesMessage.

3.12 - Provider Implementations of JMS interfaces

A provider must be prepared to accept, from a client, a message whose implementation is not one of its own. It may not be handled as efficiently as the provider's own messages, but it must be handled.

The JMS interface provides write/set methods for body and property values. "All of these methods must be implemented to copy their input objects into the message. The value of an input object is allowed to be null and will return null when accessed. One exception to this is that BytesMessage does not support the concept of a null stream, and attempting to write a null into it must throw NullPointerException.

All read/get methods of the message interfaces must be implemented to return a copy of the accessed message objects.

[Note: The emphasis on returning copies, not original references is probably to protect the integrity of the internal data. I then presumed it is safe to return immutable objects (e.g. String) without copying.]

4 JMS Common Facilities

4.2 Administered Objects

JMS defines two administered objects, Destination and Connection Factory. They should both implement javax.naming.Referenceable and java.io.Serializable to work cleanly with JNDI.

4.3 Connection

A JMS Connection is a client's active connection to its JMS provider.

  • It encapsulates an open connection with a JMS provider. It typically represents an open TCP/IP socket between a client and a provider's service daemon.
  • Its creation is where client authentication takes place.
  • It can specify a unique client identifier.
  • It creates Session objects.
  • It provides ConnectionMetaData.
  • It supports an optional ExceptionListener.

4.3.1 Authentication

If no credentials are specified, the current thread's credentials are used.

4.3.2 Client Identifier

The preferred way to assign a client's client identifier is for it to be configured in a client-specific ConnectionFactory and transparently assigned to the connection it creates.

If a connection has an existing ID, an attempt to change it by setting it must throw an IllegalStateException.

If a client explicitly does the set it must do this immediately after creating the connection and before any other action on the connection is taken. After that point throw an IllegalStateException.

4.3.3 Connection Setup

A MessageProducer can send messages while a Connection is stopped.

Clients Rely on the fact that no messages are delivered by a connection until it has been started. JMS provders must insure that this is the case.

4.3.4 Pausing Delivery of Incoming Messages

When the connection is stopped, delivery to all the connection's MessageConsumers is inhibited: synchronous receives block, and messages are not delivered to MessageListeners.

Stopping a connection has no effect on its ability to send messages. Stopping a stopped connection and starting a started connection are ignored.

A stop method call must not return until delivery of messages has paused. The receive timers for a stopped connection continue to advance.

If MessageListeners are running when stop is invoked, stop must wait until all of them have returned before it may return. While these MessageListeners are completing, they must have the full services of the connection available to them.

4.3.5 Closing a Connection

A close terminates all pending message receives on the connection's session consumers.

A message consumer will likely get an exception if it is attempting to use a closed connection while processing its last message. A developer must take this "last message" case into account when writing a message consumer. It bears repeating that the message consumer cannot rely on a null return value to indicate this "last message" case.

All the facilities of the connection and its sessions must remain available to the connection's session's message listeners until they return control to the JMS provider.

Connection close() should not return until message processing has been shut down in an orderly fashion and all pending receives have returned.

If a connection is closed, all resources for the connection should be released recursively.

Closing a connection must roll back transactions in progress.

Invoking the acknowledge method of a received message from a closed connection must throw an IllegalStateException.

Once a connection has been closed, an attempt to use it or its sessions or their message consumers and producers must throw an IllegalStateException.

Closing a closed connection must not throw an exception.

A connection is a factory for sessions.

4.3.7 ConnectionMetaData

A Connection provides a ConnectionMetaData object. This object provides the latest version of JMS supported by the provider as well as the provider's product name and version.

It also provides a list of the JMS defined property names supported by the connection.

4.3.8 ExceptionListener

If a JMS provider detects a problem with a connection, it will inform the connection's ExceptionListener. It allows a client to be asynchronously notified of a problem.

If no ExceptionListener is registered connection.getExceptionListener() returns null.

A Connection serializes execution of its ExceptionListener.

A provider should attempt to resolve the problems itself before notifying the client. If an exception is thrown on a JMS call it, by definition, must not be delivered to an ExceptionListener. ExceptionListener is not for the purpose of monitoring all exceptions.

4.4 Session

  • A factory for MessageProducers and MessageConsumers
  • A factory for TemporaryTopics and TemporaryQueues
  • Provides a way to create Queue or Topic objects for clients that need to dynamically manipulate provider-specific destination names.
  • Supplies provider-optimized message factories.
  • Supports a single series of transactions that combine work spanning this session's producers and consumers into atomic units.
  • Defines a serial order for the messages it consumes and the messages it produces.
  • Retains messages it consumes until they have been acknowledged.
  • Serializes execution of MessageListeners registered with it.
  • A factory for QueueBrowsers.

4.4.1 Closing a Session

Session close must handle pending receives by the session's consumers or a running message listener before returning.

Session close is the only session method that may be invoked by an outside thread.

Session close should recursively release all its resources.

Closing a transacted session must roll back its transaction in progress.

Once a session has been closed, an attempt to use it or its message consumers and producers must throw an IllegalStateException.

Closing a closed session must NOT throw an exception.

4.4.2 MessageProducer and MessageConsumer Creation

Although a session may create multiple producers and consumers, they are restricted to serial use. Only a single logical thread can use them.

4.4.3 Creating Temporary Destinations

Temporary destinations (TemporaryQueue or TemporaryTopic objects) are destinations that are system generated uniquely for their connection. Only their own connection is allowed to create MessageConsumers for them

Each TemporaryQueue or TemporaryTopic object is unique. It cannot be copied.

They will automatically be deleted when they are garbage collected or when their connection is closed.

4.4.5 Optimized Message Implementations

Sessions must be capable of sending all JMS messages regardless of how they may be implemented

4.4.6 Conventions for using a Session

Sessions are designed for serial use by on thread at a time.

One typical use is to have a thread block on a synchronous MessageConsumer until a message arrives. The thread may then use one or more of the session's MessageProducers.

A session with message listeners cannot also be used to synchronously receive messages. [Enforce.]

A connection must be in stopped mode to set up a session with more than one message listener. The reason is once the first message listener has been registered, the session is now controlled by the thread that delivers messages to it, and a client thread cannot be used to further configure.

4.4.7 Transactions

A sesion may optionally be specified as transacted. Transactions organize a session's input message stream and output message stream into series of atomic units. When a transaction commits, its atomic unit of input is acknowledged and its associated atomic unit of output is sent. If a transaction rollback is done, its produced messages are destroyed and its consumed messages are automatically recovered.

The completion of a session's current transaction automatically begins the next. The result is that a transacted session always has a current transaction.

Since Java distributed transactions are controlled via the JTA transaction demarcation API, use of the session's commit and rollback methods in this context throw a JMS TransactionInProgressException.

4.4.8 Distributed Transactions

JMS does not require that a provider support distributed transactions; however, if a provider supplies this support it should be done via the JTA XAResource API.

[We will defer this functionality.]

4.4.9 Multiple Sessions

For Pub/Sub, if two sessions each have a TopicSubscriber that subscribes to the same Topic, each subscriber is given each message. Delivery to one subscriber does not block if the other gets behind.

Message delivery to multiple QueueReceivers [for the same Queue] will depend on the JMS provider's implementation.

4.4.10 Message Order

JMS defines that messages sent by a session to a destination must be received in the order in which they were sent.

[How to enforce? Being session-specific makes this easier, but I'm not sure SQS provides any guarantees.]

  • Messages of higher priority may jump ahead of previous lower priority messages
  • A client may not receive a NON_PERSISTENT message due to a JMS provider failure
  • If both PERSISTENT and NON_PERSISTENT messages are sent to a destination, order is only guaranteed within delivery mode. That is, a later NON_PERSISTENT message may arrive ahead of an earlier PERSISTENT message; however, it will never arrive ahead of an earlier NON_PERSISTENT message with the priority.
  • A client may use a transacted session to group its sent messages into atomic units (the producer component of a JMS transaction). A transaction's order of messages to a particular destination is significant. The order of sent messages across destinations is not significant.

4.4.11 Message Acknowledgement

If a session is transacted, message acknowledgement is handled automatically by commit, and recovery is handled automatically by rollback.

If a session isnot transacted there are three acknowledgement options, and recover is handled manually:

  • DUPS_OK_ACKNOWLEDGE - The session lazily acknowledges the delivery of messages. This likely results in duplicates if JMS fails, so it should only be used by consumers that are tolerant of dups.
  • AUTO_ACKNOWLEDGE - The session automatically acknowledges a client's receipt of a message when it has either successfully returned from the receive() call or the MessageListener that is processing the message successfully returns.
  • CLIENT_ACKNOWLEDGE - A client acknowledges a message by calling the message's acknowledge() method. Acknowledging a consumed message automatically acknowledges the receipt of all messages that have been delivered by its session.

In CLIENT_ACKNOWLEDGE mode, a client may build up a large number of unacknowledged messages while attempting to process them. JMS provider should provide administrators with a way to limit client over-run.

A session recover() method is used to stop a session and restart it with its first unacknowledged message.

A session must set the redelivered flag of messages it redelivers due to a recovery.

4.4.12 Duplicate Delivery of Messages

A JMS provder must never deliver a second copy of an acknowledged message

[This is not absolutely guaranteed by AWS. Provide a per-connection filter to mitigate? Collect some statistics on the risk?]

4.4.13 Duplicate Production of Messages

JMS providers must never produce duplicate messages, even in the case of client error.

4.5 MessageConsumer

A MessageConsumer is created by passing a Queue or Topic to a Sessions's createConsumer method.

4.5.2 Asynchronous Delivery

It is possible fo a listener to throw a RuntimeException; however this is considered a client programming error. [This is actually pretty standard practice by clients with recoverable errors. Optional feature: provide optional retry counter, backoff logic, and dead letter queue for N failed retries.]

The result of a listener throwing a RuntimeException depends on the session's acknowledgement mode.

  • AUTO_ACKNOWLEDGEMENT or DUPS_OK_ACKNOWLEDGE - the message will be immediately redelivered. The number of attempts is provider-dependent. The JMSRedelivered header will be set.
  • CLIENT_ACKNOWLEDGE - The next message for the listener is delivered. In this case the client must manually recover.
  • Transacted Session - The next message for the listener is delivered. RuntimeException does not automatically rollback the session, and the client must do it explicitly.

JMS providers should flag clients with message listeners that are throwing RuntimExceptions as possibly malfunctioning.

4.6 MessageProducer

A client can specify a default delivery mode, priority, and TTL for messages sent by a producer.

Each time a client creates a MessageProducer, it defines a new sequence of messages that have no ordering relationship with the messages it has previously sent. [Correlates to sec. 4.4.10]

4.7 Message Delivery Mode

  • NON_PERSISTENT mode does not require that the message be stored. A provider failure can cause message loss.
  • PERSISTENT mode should lose a message in transit due to provider failure.

[We'll probably make all messages PERSISTENT and log messages sent as NON_PERSISTENT as being an ignored mode.]

The use of PERSISTENT messages does not guarantee that all messages are always delivered to every eligible consumer. See sec. 4.10.

4.8 Message TTL

JMS does not define the accuracy provided to calculating TTL's for expiration. See Sec. 3.4.9.

4.10 Reliability

A NON_PERSISTENT message is not guaranteed if the durable subscription becomes inactive (has no current subscriber) or if the provider is restarted.

4.11 Method Inheritance across Messaging Domains

If an application attempts to call any of the methods listed the provider must throw an IllegalStateException:

  • QueueConnection - createDurableConnectionConsumer()
  • QueueSession - createDurableSubscriber(), createTemporaryTopic(), createTopic(), unsubscribe()
  • TopicSession - createQueueBrowser(), createQueue(), createTemporaryQueue()

5 - JMS Point-to-Point Model

5.1 Overview

A queue can contain a mixture of messages.

PTP domain-specific interfaces and the common facility interfaces must guarantee the same behavior.

Common interfaces are preferred in 1.1:

  • QueueConnectionFactory -> ConnectionFactory
  • QueueConnection -> Connection
  • Queue -> Destination
  • QueueSession -> Session
  • QueueSender -> MessageProducer
  • QueueReceiver -> MessageConsumer

5.2 Queue Management

JMS does not define facilites for creating, administering, or deleting long-lived queues.

5.4 Temporary Queue

A TemporaryQueue is a system-defined queue that can be consumed only by the Connection or QueueConnection that created it.

5.7 QueueSession

If there are messages that have been received but not acknowledged when a QueueSession terminates, these messages must be retained and redelivered when a consumer next accesses the queue. [Redundant to 4.4.?]

5.9 QueueBrowser

A client uses a QueueBrowser to look at messages on a queue without removing them.

The browse methods return a java.util.Enumeration that is used to scan the queue's messages.

Messages may be arriving and expiring while the scan is done. JMS does not require the content of an enumeration to be a static snapshot of queue content.

5.10 QueueRequestor

The QueueRequestor constructor is given a QueueSession and a destination queue. It creates a TemporaryQueue for the responses and provides a request method that sends the request message and waits for its reply.

[Defer]

6 JMS Publish/Subscribe Model

6.1 Overview

Pub/Sub domain-specific interfaces and common interfaces must guarantee the same behavior.

6.2 Pub/Sub Latency

JMS does not define the exact semantics that apply during the interval when a pub/sub provider is adjusting to a new client.

6.3 Durable Subscription

Nondurable subscriptions last for the lifetime of their subscriber object

A durable subscriber registers a durable subscription with a unique identity that is retained by JMS.

All JMS providers must be able to run JMS applications that dynamically create and delete durable subscriptions.

[Can't defer past 1.0, but this may be complicated, so save this for later.]

6.6 TemporaryTopic

A TemporaryTopic is a unique Topic object created for the duration of a Connection or TopicConnection. It can be consumed only by the connection that created it.

By definition, it does not make sense to create a durable subscription to a temporary topic. [Throw an exception if detected.]

6.9 TopicSession

unsubcribe() method deletes a session's client's durable subscriptions

6.11 TopicSubscriber

Ordinary TopicSubscribers are not durable.

The subscriber NoLocal attribute allows a subscriber to inhibit the delivery of messages published by its own connection.

Each copy of the message distributed to different subscribers is treated separtely. Work done on one copy of a message has no effect on any other; acknowledging one does not acknowledge any other.

6.11.1 Durable TopicSubscriber

JMS retains a recored of durable subscription and insures that all messages from the Topic's publishers are retained until either they are acknowledged or have expired.

Sessions with durable subscribers must always provide the same client identifier. In addition, each client must specify a name that uniquely identifies (within client identifier) each durable subscription it creates. Only one session at a time can have a TopicSubscriber for a particular durable subscription. (See 4.3.2 for more info.)

A client can change an existing durable subscription by creating a durable TopicSubscriber with the same name and a new topic and/or message selector, or NoLocal attribute. Changing a durable subscription is equivalent to deleting and recreating it.

It is erroneous for a client to delete a durable subscription while it has an active TopicSubscriber for it or while a message received by it is part of a current transaction or has not been acknowledged by the session.

6.12 Recovery and Redelivery

Sending a message to a topic with a delivery mode of PERSISTENT does not alter this model of recovery and redelivery.

6.13 Administering Subscriptions

The amount of resources allocated for message storage and the consequences fo resource overflow are not defined by JMS.

6.14 TopicRequestor

The TopicRequestor constructor is given a TopicSession and a destination topic. It creates a TemporaryTopic for the responses and provides a request() method that sends the request message and waits for its reply.

7 JMSExceptions

7.2 The JMSException

JMS defines JMSException as the root class for all exceptions thrown by JMS methods.

JMS defines the following standard exceptions:

  • IllegalStateException - Must be throw if Session.commit() is called on a non-transacted session. Must be called when domain inappropriate method is called (e.g. TopicSession.createQueueBrowser())
  • JMSSecurityException - Must be thrown when a provider rejects authentication
  • InvalidClientIDException - Must be thrown when a provider rejects a client identifier
  • InvalidDestinationException - Must be thrown when a destination is not understood or is no longer valid
  • InvalidSelectorException - Must be thrown in case of a selector syntax error
  • MessageEOFException - Must be thrown when an unexpected end of stream while reading StreamMessage or ByteMessage
  • MessageFormatException - Must be thrown when a client attempts to use a data type unsupported by a message, or attempts to read data in a message as the wrong type. It must be thrown if StreamMessage.writeObject is given an unsupported class, or if, for example, StreamMessage.readShort() is used to rad a boolean. Must be thrown if a provider is given a type of message it cannot accept. (Note that reading an improperly formatted String as a numeric throws a NumberFormatException instead.)
  • MessageNotReadableException - Must be thrown when JMS client attempts to read a write-only message
  • MessageNotWritabelException - Must by thrown when client attempts to write to a read-only message
  • ResourceAllocationException - Thrown when a provider is unable to allocate resources required by a method. (e.g unable to create connection)
  • TransactionInProgressException - Thrown when an operation [e.g. commit/rollback] is invalid because a transaction is in progress.
  • TransactionRolledBackException - Must be thrown when a call to commit results in a rollback of the current transaction.
Clone this wiki locally