jms-spec

JMS (Java Message Service) Specification

More flexible JMS MDBs (Version 2)

This page contains some proposals for JMS 2.1 that were being considered by the expert group before work was halted and JSR 368 withdrawn. It is retained here as a historical record and in case it proves useful to a future JMS expert group. See also the main JMS 2.1 page

This page contains version 2 of proposals to simplify the configuration of JMS MDBs in JMS 2.1 and Java EE 8. See the summary of changes compared to Version 1 of these proposals.

These proposals supersede version 1.

These proposals were superseded by version 3, version 4 and version 5.

Contents

Changes from version 1

If you haven’t read version 1 then you may prefer to skip this section and go straight to the following section, Background. When you’ve read the rest you may wish to come back here and review the list of new issues added in this section.

Multiple callback methods

  • A MDB may define multiple callback methods. The earlier proposal to allow only a single callback method has been dropped. Each callback method will be treated as representing a separate consumer, and so may specify a different queue or topic, connection factory, durable subscription, message selector etc.
New Issue I17: Should multiple callback methods be permitted or should MDBs be restricted to a single callback method as in the previous version?. There is an argument that allowing multiple callback methods may be confusing for developers, who may not realise the concurrency implications. It may also make implementation more complex for application servers that automatically calculate the size of the MDB pool. Comments are invited.

Allowed return types

  • The callback method must return void. The earlier proposal to allow any return type, but ignore any returned value, has been dropped since it prevents a future version of JMS defining behaviour for returned values. If the @JMSListener annotation is used on a method which does not return void then deployment must fail. If a resource adapter is used then endpointActivation must throw an exception.

Required annotations

  • Each callback method must be annotated with @JMSListener. If this annotation is omitted then the method will not be treated as a callback method; any other callback annotations are ignored. (This restriction does not apply to the javax.jms.MessageListener method onMessage(Message m)).
New Issue I18: Should we relax the requirement for each callback method (other than the javax.jms.MessageListener method `onMessage(Message m)`) to be annotated with @JMSListener, and allow the presence of any of the annotations @JMSConnectionFactory, @JMSListener, @SubscriptionDurability, @ClientId, @SubscriptionName, @MessageSelector or @Acknowledge to be sufficient to designate a callback method?

If the MDB implements javax.jms.MessageListener

  • If the MDB implements javax.jms.MessageListener then the new callback annotations may be applied to the onMessage(Message m) method. Any of the new callback annotations may be specified; it is not necessary to specify @JMSListener.

  • If the MDB implements javax.jms.MessageListener then application-defined callback methods (in addition to onMessage(Message m)) may only be implemented if the MDB is explicitly configured to specify that its listener interface is JMSMessageDrivenBean (e.g. by using the annotation @MessageDriven(messageListenerInterface=JMSMessageDrivenBean.class)). This is required to satisfy the requirements of EJB 3.2 section 5.6.5 “Message-Driven Bean with No-Methods Listener Interface”. EJB spec issue 126 proposes the removal of this requirement.

New Issue I19: This requirement may be a cause of unexpected errors, since the resource adapter has no way to verify at deployment time whether the MDB has been configured to specify that its listener interface is JMSMessageDrivenBean. The endpointActivation method has no access to this information. This means that the resource adapter will only discover when it tries to deliver a message that the message endpoint does not implement the callback method. Note that although endpointActivation has access to an instance of MessageEndpointFactory this cannot be used to examine what methods are implemented by the endpoint class since it may not be valid to call createEndpoint until after deployment has completed. Note that EJB spec issue 126 would remove this issue.

Incompatible method parameters

  • The earlier proposal to set a parameter to null if it cannot be set because its type is incompatible has been dropped.

  • If any of the parameters of the callback method cannot be set because they have an incompatible type then callback method will not be invoked. Such messages may either be discarded or delivered to a provider-specific dead message queue.

New Issue I20: Is this an adequate definition of the required behaviour when parameters of the callback method cannot be set?

Callback methods that throw exceptions

  • Callback methods will be allowed to declare and throw exceptions. Exceptions thrown by the callback method (including unchecked exceptions thrown by the onMessage method of a MessageListener) will be handled by the EJB container as defined in the EJB 3.2 specification section 9.3.4 “Exceptions thrown from Message-Driven Bean Message Listener methods”. This defines whether or not any transaction in progress is committed or rolled back, depending on whether or not the exception is a “system exception” or an “application exception”, whether or not the application exception is specified as causing rollback, and whether or not the application has called setRollbackOnly. It also defines whether or not the MDB instance is discarded. If the transaction is rolled back, or a transaction is not being used, then the message will be redelivered.

  • The JMS provider should detect repeated attempts to redeliver the same message to a MDB. Such messages may either be discarded or delivered to a provider-specific dead message queue. (Note that this not completely new to JMS: JMS 2.1 section 8.7 refers to a JMS provider “giving up” after a message has been redelivered a certain number of times).

New Issue I21: Is this an adequate definition of the required behaviour when a callback method throws an exception?

Other changes

  • The ability to specify the queue or topic by destination name rather than JNDI name has been removed because JMS considers this name to be non-portable. If possible, JMS 2.1 will define a portable way to obtain a Queue or Topic object that doesn’t require JNDI, though this will be kept as a separate issue.

Other new issues

Issue I22: How about replacing @JMSListener with separate @JMSQueueListener and @JMSTopicListener annotations? This would remove the need for a separate "type" attribute.
Issue I23: Currently the acknowledgeMode activation property is rather confusing, as it is ignored when the bean is configured to use container-managed transactions. It is only used when the MDB is configured to use bean-managed transactions, such as with the class-level annotation @TransactionManagement(TransactionManagementType.BEAN). The same confusion will apply if we define the new @Acknowledge annotation to work the same way as acknowledgeMode.

In fact if you want the MDB to consume messages without a transaction and using automatic-acknowledgement then all you need to do is to set @TransactionManagement(TransactionManagementType.BEAN). You don't actually need to set the acknowledgeMode activation property, since it defaults to auto-ack anyway. The only reason you ever need to use the acknowledgeMode activation property is if you wanted to specify DUPS_OK.

We can't change the behaviour of acknowledgeMode, but it would be better if we could replace the existing @TransactionManagement annotation and the proposed @AcknowledgeMode annotation with a single annotation which could define both at the same time.

Background

There have been several proposals to improve the ways that JMS applications can consume messages asynchronously:

  • In JMS spec issue 116 John Ament proposed (back in March 2013, just as JMS 2.0 was being finalised) improving the ways that JMS MDBs were defined, taking advantage of some new features that were added to EJB 3.2 and JCA 1.7 (at the suggestion of David Blevins) just before they were released.

  • In JMS spec issue 134 Reza Rahman proposed that JMS defined some annotations that allowed any CDI bean to listen for JMS messages

  • In JMS spec issue 100 Bruno Borges proposed improving the ways that JMS MDBs were defined, though in the subsequent discussion he proposed that this could be extended to other types of Java EE class such as session beans. That makes this essentially a combination of the other two proposals.

Goals

The proposals on this page are addressed at the first of these proposals, JMS spec issue 116:

  • The requirement for a MDB that consumes JMS messages to implementjavax.jms.MessageListener will be removed.

  • Instead of having to provide a callback method void onMessage(Message m), the callback method may have any name and can have multiple parameters of a variety of types. The developer can use parameter annotations to specify that a parameter must be set to the message object, to the message body, or to a specified message header or message property.

  • Instead of having to use the general-purpose activation property mechanism to define what messages the MDB will receive, the developer can specify a set of JMS-specific annotations. This is more obvious, less verbose and allows the compiler to detect spelling errors.

These new annotations will initially be available only on MDBs. This offers a large scope for improvement without the need to consider issues such as listener lifecycle, listener pooling and resource adapter integration. A later stage in the development of JMS 2.1 will consider extending them to other types of Java EE object such as CDI managed beans.

Specifying the callback method

In Java EE 7, a JMS MDB must implement the javax.jms.MessageListener interface. This means that the callback method must be called onMessage, it must return void and it must have a single parameter of type Message.

@MessageDriven(activationConfig = {
  @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "java:global/requestQueue"),
  @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class MyMessageBean implements MessageListener {
 
  public void onMessage(Message message){
    ...
  }
 
}

Although this option will remain, it is proposed in Java EE 8 to remove the requirement for a JMS MDB to implement the javax.jms.MessageListener interface. Instead the developer can use the @JMSListener annotation to designate any method to be the callback method.

@MessageDriven
public class MyMessageBean <b>implements JMSMessageDrivenBean</b> {
 
  @JMSListener(lookup="java:global/Trades", type=JMSListener.Type.QUEUE)
  public void processTrade(TextMessage tradeMessage){
    ...
  }
 
}

This is still a MDB

  • The listener class is still a message-driven bean and so must be configured as one, either by adding the @MessageDriven annotation or using the <message-driven> element in the deployment descriptor. It may also be necessary to specify which resource adapter should be used.

Application-defined callback methods

  • A JMS MDB may have any number of application-defined callback methods. Each callback method will be treated as representing a separate consumer, and so may specify a different queue or topic, connection factory, durable subscription, message selector etc.

  • Each application-defined callback method must be specified using the annotation @JMSListener. The @JMSListener annotation may also be used to specify the queue or topic from where messages are to be received. Additional information about how the consumer is configured may be specified using the annotations @JMSConnectionFactory, @Acknowledge, @SubscriptionDurability, @ClientId, @SubscriptionName or @MessageSelector.

  • A callback method may have any number of parameters. Depending on the parameter type and any parameter annotations, each parameter will may be set to the message, the message body, a message header or a message property.

  • Each application-defined callback method must return void.

  • An MDB with application-defined callback methods must implement the interface javax.jms.JMSMessageDrivenBean This is a new marker interface which defines no methods, and is required to satisfy the requirements of EJB 3.2 section 5.6.5 “Message-Driven Bean with No-Methods Listener Interface”. (Note that it is hoped that the EJB spec can be updated so that this marker interface will not actually be needed. See EJB spec issue 115 and EJB spec issue 126)

  • Both the callback method and the JMSMessageDrivenBean interface may be inherited.

MDBs that implement javax.jms.MessageListener

  • JMS MDBs may continue to implement javax.jms.MessageListener as they do now. In this case they must implement the callback method onMessage(Message m). Any (or none) of the new callback annotations may be applied to this method; it is not necessary to specify @JMSListener.

  • If the MDB implements javax.jms.MessageListener then additional callback methods (in addition to onMessage(Message m)) may only be implemented if the MDB also implements JMSMessageDrivenBean and is also explicitly configured to specify that its listener interface is JMSMessageDrivenBean (e.g. by using the annotation @MessageDriven(messageListenerInterface=JMSMessageDrivenBean.class)).

Threading rules

These proposals do not change the existing threading rules for MDBs, even for MDBs with multiple callback methods. These rules are defined in the EJB 3.2 specification:

5.4.11 Serializing message-driven bean methods The container serializes calls to each message-driven bean instance. Most containers will support many instances of a message-driven bean executing concurrently; however, each instance sees only a serialized sequence of method calls. Therefore, a message-driven bean does not have to be coded as reentrant. The container must serialize all the container-invoked callbacks (e.g., lifecycle callback interceptor methods and timeout callback methods), and it must serialize these callbacks with the message listener method calls.

Exceptions

  • Callback methods will be allowed to declare and throw exceptions. Exceptions thrown by the callback method (including unchecked exceptions thrown by the onMessage method of a MessageListener) will be handled by the EJB container as defined in the EJB 3.2 specification section 9.3.4 “Exceptions thrown from Message-Driven Bean Message Listener methods”. This defines whether or not any transaction in progress is committed or rolled back, depending on whether or not the exception is a “system exception” or an “application exception”, whether or not the application exception is specified as causing rollback, and whether or not the application has called setRollbackOnly. It also defines whether or not the MDB instance is discarded. If the transaction is rolled back, or a transaction is not being used, then the message will be redelivered.

  • The JMS provider should detect repeated attempts to redeliver the same message to a MDB. Such messages may either be discarded or delivered to a provider-specific dead message queue. (Note that this not completely new to JMS: JMS 2.1 section 8.7 refers to a JMS provider “giving up” after a message has been redelivered a certain number of times).

Implementation

  • Application servers that implement JMS MDBs using a resource adapter should be able to implement these new features by enhancing the resource adapter itself. Few changes to the EJB container itself will be required. Application servers that implement JMS MDBs directly, without using a resource adapter, will of course need to implement these features in the EJB container itself.

Specifications affected

  • Since MDBs are defined in the EJB specification, not the JMS specification, it will almost certainly be necessary to work with the EJB maintenance lead to create a revision of the EJB spec containing these new features.

  • In the JMS specification itself, chapter 13 “Resource adapter” (which contains optional recommendations for a JMS resource adapter) will be extended to cover these new features.

Issue I1: Deleted
Issue I2: Deleted
Issue I3: The EJB specification does not define a standard way to associate a MDB with a resource adapter. JMS MDBs that require the use of a resource adapter will continue to need to specify the resource adapter in a non-portable way, either using the app-server-specific deployment descriptor (e.g. `glassfish-ejb-jar.xml`) or by using a default resource adapter provided by the application server. (Note that it is hoped that the EJB specification can be updated to define a standard way to associate a MDB with a resource adapter. See EJB spec issue 127.
Issue I4: Deleted (superseded by New Issue I17)
Issue I5: It would be desirable to avoid the need to implement `javax.jms.JMSMessageDrivenBean` since this is needed purely to satisfy EJB 3.2. EJB spec issue 115 and EJB spec issue 126 propose removal of this requirement from the next version of EJB.
Issue I6: The reason why these annotations cannot be applied to the `onMessage` method of a `MessageListener` is that `MessageListener` is not a no-method interface, which means the resource adapter cannot access the methods of the MDB implementation class. It may be possible to change the EJB specification to allow this restriction to be removed.

Specifying what messages will be received

Before it can be used, a JMS MDB must specify where the messages will come from and how they will be received. In Java EE 7 these are specified using “activation properties”, each of which has a String name and a String value. The name and value of each property must be hardcoded into either the application code or the deployment descriptor, and the developer gets no help from the compiler or schema to check that they are using the correct name and setting it to an appropriate value. The syntax itself is also cumbersome.

@MessageDriven(activationConfig = {
  @ActivationConfigProperty(
    propertyName = "connectionFactoryLookup", propertyValue = "java:global/MyCF"),
  @ActivationConfigProperty(
    propertyName = "destinationLookup", propertyValue = "java:global/java:global/Trades"),
  @ActivationConfigProperty
    (propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
  @ActivationConfigProperty(
    propertyName = "clientId", propertyValue = "Consumer123"),
  @ActivationConfigProperty(
    propertyName = "subscriptionDurability", propertyValue = "Durable"),
  @ActivationConfigProperty(
    propertyName = "subscriptionName", propertyValue = "Subscription456"),
  @ActivationConfigProperty(
    propertyName = "messageSelector", propertyValue = "ticker='ORCL'")
}
public class MyMessageBean implements MessageListener {
  ...
}

In Java EE 8 a JMS MDB may continue to specify activation properties, even if the MDB does not implement javax.jms.MessageListener. However they will be superseded by a new set of JMS-specific annotations which allow each activation property to be configured by a JMS-specific annotation on the callback method itself.

@JMSListener(lookup="java:global/java:global/Trades",type=JMSListener.Type.TOPIC )
@JMSConnectionFactory("java:global/MyCF")
@SubscriptionDurability(SubscriptionDurability.Mode.DURABLE)
@ClientId("myClientID1")  
@SubscriptionName("mySubName1")
@MessageSelector("ticker='ORCL'")
@Acknowledge(Acknowledge.Mode.DUPS_OK_ACKNOWLEDGE)
public void giveMeAMessage(Message message) {
  ...
}

These annotations are introduced in more detail in the following sections.

Issue I7: Any alternative proposals for the @JMSConnectionFactory, @Acknowledge, @SubscriptionDurability, @ClientId, @SubscriptionName or @MessageSelector annotations?
Issue I8: Should JMS define a set of deployment descriptor which correspond to these annotations, and which can be used by a deployer to override them? This would require a major change to the EJB and JCA specs since a resource adapter cannot currently access the deployment descriptor. A slightly simpler alternative might be to require the EJB container to convert these deployment descriptor elements to activation properties and pass them to the resource adapter in the activation spec.
Issue I9: What happens if the same attribute is specified using an activation property and using one of these new annotations? It is proposed that a value defined using an activation property always overrides the same property defined using one of these new annotations, since this would provide a way to override these new annotations in the deployment descriptor.
Issue I10: Is an additional annotation required to allow non-standard properties to be passed to the resource adapter or container? Or are activation properties adequate for this purpose?

Specifying the queue or topic

The @JMSListener method annotation must always be supplied (except in the special case of the onMessage method of a MessageListener). It designates (1) the method as being a listener callback method and optionally (2) the destination from which messages are to be received and (3) whether the specified destination is a queue or topic.

The lookup attribute may be used to specify the JNDI name of the queue or topic. This corresponds to the existing EJB 3.2 activation property destinationLookup.

@JMSListener(lookup="java:global/Trades", type=JMSListener.Type.Topic)

The @JMSListener method annotation also has a mandatory attribute type. This must be used to specify whether the destination is a queue or topic. This corresponds to the existing EJB 3.2 activation property destinationType, though the attribute is an enumerated type rather than a String.

Issue I11: Deleted
Issue I12: The EJB and Java EE specifications currently define a number of other ways of defining the destination used by the MDB, such as by setting the `mappedName` attribute of the `@MessageDriven` annotation. The specification will need to clarify the override order used if the destination is specified in multiple ways.
Issue I13: Is it right that the @JMSListener attribute type is mandatory,? The existing EJB 3.2 activation property destinationType does not define a default value. Should it remain optional, in which case should the specification designate a default value when @JMSListener is used?

Specifying the connection factory

The existing @JMSConnectionFactory annotation may be used to specify the JNDI name of the connection factory used to receive messages.This corresponds to the existing EJB 3.2 activation property connectionFactoryLookup.

@JMSConnectionFactory("java:global/MyCF")

Note that @JMSConnectionFactory is an existing annotation which is currently used to configure the connection factory used to create an injected JMSContext object. It better to reuse this annotation than have two very similar annotations.

Specifying the acknowledgement mode when using bean-managed transactions

The existing @Acknowledge annotation may be used to specify the acknowledgement mode that will be used if bean-managed transaction demarcation is used. This corresponds to the existing EJB 3.2 activation property acknowledgeMode.

@Acknowledge(Acknowledge.Mode.DUPS_OK_ACKNOWLEDGE)

The acknowledgement mode is specified using an enumerated type Acknowledge.Mode, which is a nested type of the Acknowledge annotation.

Specifying durable topic subscriptions

If the MDB is being used to consume messages from a topic, three further annotations are available: @SubscriptionDurability, @SubscriptionName and @ClientId. These correspond to the EJB 3.2 activation properties subscriptionDurability, subscriptionName and clientId.

@MessageDriven
public class MyMessageBean implements JMSMessageDrivenBean {
 
  @Resource(mappedName = "java:global/replyQueue")
  private Queue replyQueue;

  @Inject
  private JMSContext jmsContext;
  
  @SubscriptionDurability(SubscriptionDurability.Mode.DURABLE)
  @SubscriptionName("mySubName1")
  @ClientId("myClientID1")  
  @JMSListener(lookup="java:global/inboundTopic", type=JMSListener.Type.TOPIC)
  public void giveMeAMessage(Message message) {
    ...
  }
}

The subscription durability is specified using an enumerated type SubscriptionDurability.Mode, which is a nested type of the SubscriptionDurability annotation.

Issue I14: Should the @SubscriptionDurability, @SubscriptionName and @ClientId annotations (or perhaps the first two) be combined into a single annotation?

Specifying a message selector

The @MessageSelector annotation may be used to specify the message selector to be used. This corresponds directly to the EJB 3.2 activation property messageSelector, which may be used to override it.

@MessageDriven
public class MyMessageBean implements JMSMessageDrivenBean {
 
  @MessageSelector("JMSType = 'car' AND colour = 'blue'")
  @JMSListener(lookup="java:global/requestQueue", type=JMSListener.Type.QUEUE)
  public void giveMeAMessage(Message message) {
    ...
  }

Flexible method signature

When a message is delivered the container will set each method parameter to the message, the message body or to a message header or property, depending on the type of the message, the type of the parameter, and any @MessageHeader or @MessageProperty annotation.

Message parameters

A parameter may be Message or one of its five subtypes TextMessage, StreamMessage, BytesMessage, MapMessage, ObjectMessage. This avoids the need for the listener method to cast the Message to the expected subtype.

void processTrade(TextMessage textMessage){
  ...
}

Parameters for message body

If the message is a TextMessage then any parameter of type String (and which is not annotated with @MessageHeader or @MessageProperty) will be set to contain the message body.

void processTrade(String messageText){
  ...
}

If the message is a ObjectMessage then any parameter to which the message body is assignable (and which is not annotated with @MessageHeader or @MessageProperty) will be set to contain the message body.

void processTrade(Trade incomingTrade){
  ...
}

If the message is a MapMessage then any parameter of type Map (and which is not annotated with @MessageHeader or @MessageProperty) will be set to contain the message body.

void processTrade(Map tradeData){
  ...
}

If the message is a BytesMessage then any parameter of type byte[] (and which is not annotated with @MessageHeader or @MessageProperty) will be set to contain the message body.

void processTrade(byte[] tradeBytes){
  ...
}

Message headers

The @MessageHeader annotation may be used to specify that a parameter should be set to the specified message header.

void processTrade(TextMessage messageText, @MessageHeader(Header.JMSCorrelationID) String correlationId,){
  ...
} 

The message header is specified using an enumerated type MessageHeader.Header, which is a nested type of the MessageHeader annotation.

Message properties

The @MessageProperty annotation may be used to specify that a parameter should be set to the specified message property.

void processTrade(TextMessage messageText, @MessageProperty("price") long price,){
  ...
} 

Summary of callback method parameters

The following table lists all the options available for customising the method parameters:

Message type Parameter type Annotation Set to
TextMessage TextMessage None The TextMessage object
StreamMessage StreamMessage None The StreamMessage object
BytesMessage BytesMessage None The BytesMessage object
MapMessage MapMessage None The MapMessage object
ObjectMessage ObjectMessage None The ObjectMessage object
Message Message None The Message object
Any someClass None The message body, if it can be converted to the specified type using message.getBody(someClass) without throwing a MessageFormatException
Any String @MessageHeader(Header.JMSCorrelationID) message.getJMSCorrelationID().
Any byte[] @MessageHeader(Header.JMSCorrelationIDAsBytes) message.getJMSCorrelationIDAsBytes().
Any Integer or int @MessageHeader(Header.JMSDeliveryMode) message.getJMSDeliveryMode().
Any Long or long @MessageHeader(Header.JMSDeliveryTime) message.getJMSDeliveryTime().
Any Destination @MessageHeader(Header.JMSDestination) message.getJMSDestination().
Any Long or long @MessageHeader(Header.JMSExpiration) message.getJMSExpiration().
Any String @MessageHeader(Header.JMSMessageID) message.getJMSMessageID().
Any Integer or int @MessageHeader(Header.JMSPriority) message.getJMSPriority().
Any Boolean or boolean @MessageHeader(Header.JMSRedelivered) message.getJMSRedelivered().
Any Destination @MessageHeader(Header.JMSReplyTo) message.getJMSReplyTo().
Any Long or long @MessageHeader(Header.JMSTimestamp) message.getJMSTimestamp().
Any String @MessageHeader(Header.JMSType) message.getJMSType().
Any Boolean or boolean @MessageProperty("foo") message.getBooleanProperty("foo")
if this returns without throwing a MessageFormatException
Any byte @MessageProperty("foo") message.getByteProperty("foo")
if this returns without throwing a MessageFormatException
Any Short or short @MessageProperty("foo") message.getShortProperty("foo")
if this returns without throwing a MessageFormatException
Any Integer or int @MessageProperty("foo") message.getIntProperty("foo")
if this returns without throwing a MessageFormatException
Any Long or long @MessageProperty("foo") message.getLongProperty("foo")
if this returns without throwing a MessageFormatException
Any Float or float @MessageProperty("foo") message.getFloatProperty("foo")
if this returns without throwing a MessageFormatException
Any Double or double @MessageProperty("foo") message.getDoubleProperty("foo")
if this returns without throwing a MessageFormatException
Any String @MessageProperty("foo") message.getStringProperty("foo")
if this returns without throwing a MessageFormatException

Incompatible method parameters

If the callback method parameter cannot be set, either because it does not match any of the cases in the preceding table, or because a MessageFormatException was encountered whilst trying to convert the required value to the specified type, then the callback method will not be invoked. The message may either be discarded or delivered to a provider-specific dead message queue.

Issue I15: Deleted
Issue I16: Deleted

Note: The javadocs for this proposal are no longer available.

New or modified? Interface or annotation? Name Link to javadocs
New Marker interface javax.jms.JMSMessageDrivenBean (Javadocs no longer available)
New Method annotation javax.jms.JMSListener (Javadocs no longer available)
Modified Method or field annotation javax.jms.JMSConnectionFactory (Javadocs no longer available)
New Method annotation javax.jms.Acknowledge (Javadocs no longer available)
New Method annotation javax.jms.SubscriptionDurability (Javadocs no longer available)
New Method annotation javax.jms.SubscriptionName (Javadocs no longer available)
New Method annotation javax.jms.ClientId (Javadocs no longer available)
New Method annotation javax.jms.MessageSelector (Javadocs no longer available)
New Parameter annotation javax.jms.MessageHeader (Javadocs no longer available)
New Parameter annotation javax.jms.MessageProperty (Javadocs no longer available)