org.springframework.jms.listener

## Class AbstractPollingMessageListenerContainer

- java.lang.Object
- - org.springframework.jms.support.JmsAccessor
  - - org.springframework.jms.support.destination.JmsDestinationAccessor
    - - org.springframework.jms.listener.AbstractJmsListeningContainer
      - - org.springframework.jms.listener.AbstractMessageListenerContainer
        - - org.springframework.jms.listener.AbstractPollingMessageListenerContainer

All Implemented Interfaces:
  org.springframework.beans.factory.Aware, org.springframework.beans.factory.BeanNameAware, org.springframework.beans.factory.DisposableBean, org.springframework.beans.factory.InitializingBean, org.springframework.context.Lifecycle, org.springframework.context.Phased, org.springframework.context.SmartLifecycle, MessageListenerContainer

Direct Known Subclasses:
  DefaultMessageListenerContainer

    public abstract class AbstractPollingMessageListenerContainer
    extends AbstractMessageListenerContainer

Base class for listener container implementations which are based on polling. Provides support for listener handling based on `MessageConsumer`, optionally participating in externally managed transactions.

This listener container variant is built for repeated polling attempts, each invoking the `receiveAndExecute(java.lang.Object, javax.jms.Session, javax.jms.MessageConsumer)` method. The MessageConsumer used may be reobtained fo reach attempt or cached in between attempts; this is up to the concrete implementation. The receive timeout for each attempt can be configured through the `"receiveTimeout"` property.

The underlying mechanism is based on standard JMS MessageConsumer handling, which is perfectly compatible with both native JMS and JMS in a Java EE environment. Neither the JMS `MessageConsumer.setMessageListener` facility nor the JMS ServerSessionPool facility is required. A further advantage of this approach is full control over the listening process, allowing for custom scaling and throttling and of concurrent message processing (which is up to concrete subclasses).

Message reception and listener execution can automatically be wrapped in transactions through passing a Spring `PlatformTransactionManager` into the `"transactionManager"` property. This will usually be a `org.springframework.transaction.jta.JtaTransactionManager` in a Java EE environment, in combination with a JTA-aware JMS ConnectionFactory obtained from JNDI (check your application server's documentation).

This base class does not assume any specific mechanism for asynchronous execution of polling invokers. Check out `DefaultMessageListenerContainer` for a concrete implementation which is based on Spring's `TaskExecutor` abstraction, including dynamic scaling of concurrent consumers and automatic self recovery.

Since:
  2.0.3
Author:
  Juergen Hoeller
See Also:
  `createListenerConsumer(javax.jms.Session)`, `receiveAndExecute(java.lang.Object, javax.jms.Session, javax.jms.MessageConsumer)`, `setTransactionManager(org.springframework.transaction.PlatformTransactionManager)`

### Nested Class Summary

### Nested classes/interfaces inherited from class org.springframework.jms.listener.AbstractJmsListeningContainer

`AbstractJmsListeningContainer.SharedConnectionNotInitializedException`

### Field Summary

Fields
`static long` `DEFAULT_RECEIVE_TIMEOUT` The default receive timeout: 1000 ms = 1 second.

### Fields inherited from class org.springframework.jms.listener.AbstractJmsListeningContainer

`lifecycleMonitor, sharedConnectionMonitor`

### Fields inherited from class org.springframework.jms.support.destination.JmsDestinationAccessor

`RECEIVE_TIMEOUT_INDEFINITE_WAIT, RECEIVE_TIMEOUT_NO_WAIT`

### Fields inherited from class org.springframework.jms.support.JmsAccessor

`logger`

### Fields inherited from interface org.springframework.context.SmartLifecycle

`DEFAULT_PHASE`

### Constructor Summary

Constructors
Constructor and Description
`AbstractPollingMessageListenerContainer()`

### Method Summary

All Methods Instance Methods Concrete Methods
`protected MessageConsumer` `createListenerConsumer(Session session)` Create a MessageConsumer for the given JMS Session, registering a MessageListener for the specified listener.
`protected boolean` `doReceiveAndExecute(Object invoker, Session session, MessageConsumer consumer, org.springframework.transaction.TransactionStatus status)` Actually execute the listener for a message received from the given consumer, fetching all requires resources and invoking the listener.
`protected Connection` `getConnection(JmsResourceHolder holder)` Fetch an appropriate Connection from the given JmsResourceHolder.
`protected long` `getReceiveTimeout()` Return the receive timeout (ms) configured for this listener container.
`protected Session` `getSession(JmsResourceHolder holder)` Fetch an appropriate Session from the given JmsResourceHolder.
`protected org.springframework.transaction.PlatformTransactionManager` `getTransactionManager()` Return the Spring PlatformTransactionManager to use for transactional wrapping of message reception plus listener execution.
`void` `initialize()` Initialize this container.
`protected boolean` `isSessionLocallyTransacted(Session session)` This implementation checks whether the Session is externally synchronized.
`protected void` `messageReceived(Object invoker, Session session)` Template method that gets called right when a new message has been received, before attempting to process it.
`protected void` `noMessageReceived(Object invoker, Session session)` Template method that gets called when no message has been received, before returning to the receive loop again.
`protected boolean` `receiveAndExecute(Object invoker, Session session, MessageConsumer consumer)` Execute the listener for a message received from the given consumer, wrapping the entire operation in an external transaction if demanded.
`protected Message` `receiveMessage(MessageConsumer consumer)` Receive a message from the given consumer.
`void` `setReceiveTimeout(long receiveTimeout)` Set the timeout to use for receive calls, in milliseconds.
`void` `setSessionTransacted(boolean sessionTransacted)` Set the transaction mode that is used when creating a JMS `Session`.
`void` `setTransactionManager(org.springframework.transaction.PlatformTransactionManager transactionManager)` Specify the Spring `PlatformTransactionManager` to use for transactional wrapping of message reception plus listener execution.
`void` `setTransactionName(String transactionName)` Specify the transaction name to use for transactional wrapping.
`void` `setTransactionTimeout(int transactionTimeout)` Specify the transaction timeout to use for transactional wrapping, in seconds.
`protected boolean` `shouldCommitAfterNoMessageReceived(Session session)` Determine whether to trigger a commit after no message has been received.

### Methods inherited from class org.springframework.jms.listener.AbstractMessageListenerContainer

`checkMessageListener, commitIfNecessary, createConsumer, doExecuteListener, doInvokeListener, doInvokeListener, executeListener, getDefaultSubscriptionName, getDestination, getDestinationDescription, getDestinationName, getDurableSubscriptionName, getErrorHandler, getExceptionListener, getMessageConverter, getMessageListener, getMessageSelector, getReplyQosSettings, getSubscriptionName, handleListenerException, invokeErrorHandler, invokeExceptionListener, invokeListener, isAcceptMessagesWhileStopping, isExposeListenerSession, isPubSubNoLocal, isReplyPubSubDomain, isSubscriptionDurable, isSubscriptionShared, rollbackIfNecessary, rollbackOnExceptionIfNecessary, setAcceptMessagesWhileStopping, setConcurrency, setDestination, setDestinationName, setDurableSubscriptionName, setErrorHandler, setExceptionListener, setExposeListenerSession, setMessageConverter, setMessageListener, setMessageSelector, setPubSubNoLocal, setReplyPubSubDomain, setReplyQosSettings, setSubscriptionDurable, setSubscriptionName, setSubscriptionShared, setupMessageListener, validateConfiguration`

### Methods inherited from class org.springframework.jms.listener.AbstractJmsListeningContainer

`afterPropertiesSet, createSharedConnection, destroy, doInitialize, doRescheduleTask, doShutdown, doStart, doStop, establishSharedConnection, getBeanName, getClientId, getPausedTaskCount, getPhase, getSharedConnection, isActive, isAutoStartup, isRunning, logRejectedTask, prepareSharedConnection, refreshSharedConnection, rescheduleTaskIfNecessary, resumePausedTasks, runningAllowed, setAutoStartup, setBeanName, setClientId, setPhase, sharedConnectionEnabled, shutdown, start, startSharedConnection, stop, stopSharedConnection`

### Methods inherited from class org.springframework.jms.support.destination.JmsDestinationAccessor

`getDestinationResolver, isPubSubDomain, receiveFromConsumer, resolveDestinationName, setDestinationResolver, setPubSubDomain`

### Methods inherited from class org.springframework.jms.support.JmsAccessor

`convertJmsAccessException, createConnection, createSession, getConnectionFactory, getSessionAcknowledgeMode, isClientAcknowledge, isSessionTransacted, obtainConnectionFactory, setConnectionFactory, setSessionAcknowledgeMode, setSessionAcknowledgeModeName`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface org.springframework.jms.listener.MessageListenerContainer

`getDestinationResolver, isPubSubDomain`

### Methods inherited from interface org.springframework.context.SmartLifecycle

`getPhase, isAutoStartup, stop`

### Methods inherited from interface org.springframework.context.Lifecycle

`isRunning, start, stop`

### Field Detail

#### DEFAULT_RECEIVE_TIMEOUT

    public static final long DEFAULT_RECEIVE_TIMEOUT

The default receive timeout: 1000 ms = 1 second.

See Also:
  Constant Field Values

### Constructor Detail

#### AbstractPollingMessageListenerContainer

    public AbstractPollingMessageListenerContainer()

### Method Detail

#### setSessionTransacted

    public void setSessionTransacted(boolean sessionTransacted)

Description copied from class: `JmsAccessor`
Set the transaction mode that is used when creating a JMS `Session`. Default is "false".

Note that within a JTA transaction, the parameters passed to `create(Queue/Topic)Session(boolean transacted, int acknowledgeMode)` method are not taken into account. Depending on the Java EE transaction context, the container makes its own decisions on these values. Analogously, these parameters are not taken into account within a locally managed transaction either, since the accessor operates on an existing JMS Session in this case.

Setting this flag to "true" will use a short local JMS transaction when running outside of a managed transaction, and a synchronized local JMS transaction in case of a managed transaction (other than an XA transaction) being present. This has the effect of a local JMS transaction being managed alongside the main transaction (which might be a native JDBC transaction), with the JMS transaction committing right after the main transaction.

Overrides:
  `setSessionTransacted` in class `JmsAccessor`
See Also:
  `Connection.createSession(boolean, int)`

#### setTransactionManager

    public void setTransactionManager(@Nullable
                                      org.springframework.transaction.PlatformTransactionManager transactionManager)

Specify the Spring `PlatformTransactionManager` to use for transactional wrapping of message reception plus listener execution.

Default is none, not performing any transactional wrapping. If specified, this will usually be a Spring `org.springframework.transaction.jta.JtaTransactionManager` or one of its subclasses, in combination with a JTA-aware ConnectionFactory that this message listener container obtains its Connections from.

Note: Consider the use of local JMS transactions instead. Simply switch the `"sessionTransacted"` flag to "true" in order to use a locally transacted JMS Session for the entire receive processing, including any Session operations performed by a `SessionAwareMessageListener` (e.g. sending a response message). This allows for fully synchronized Spring transactions based on local JMS transactions, similar to what `JmsTransactionManager` provides. Check `AbstractMessageListenerContainer`'s javadoc for a discussion of transaction choices and message redelivery scenarios.

See Also:
  `setSessionTransacted(boolean)`, `org.springframework.transaction.jta.JtaTransactionManager`, `JmsTransactionManager`

#### getTransactionManager

    @Nullable
    protected final org.springframework.transaction.PlatformTransactionManager getTransactionManager()

Return the Spring PlatformTransactionManager to use for transactional wrapping of message reception plus listener execution.

#### setTransactionName

    public void setTransactionName(String transactionName)

Specify the transaction name to use for transactional wrapping. Default is the bean name of this listener container, if any.

See Also:
  `TransactionDefinition.getName()`

#### setTransactionTimeout

    public void setTransactionTimeout(int transactionTimeout)

Specify the transaction timeout to use for transactional wrapping, in seconds. Default is none, using the transaction manager's default timeout.

See Also:
  `TransactionDefinition.getTimeout()`, `setReceiveTimeout(long)`

#### setReceiveTimeout

    public void setReceiveTimeout(long receiveTimeout)

Set the timeout to use for receive calls, in milliseconds. The default is 1000 ms, that is, 1 second.

NOTE: This value needs to be smaller than the transaction timeout used by the transaction manager (in the appropriate unit, of course). 0 indicates no timeout at all; however, this is only feasible if not running within a transaction manager and generally discouraged since such a listener container cannot cleanly shut down. A negative value such as -1 indicates a no-wait receive operation.

See Also:
  `JmsDestinationAccessor.receiveFromConsumer(MessageConsumer, long)`, `MessageConsumer.receive(long)`, `MessageConsumer.receiveNoWait()`, `MessageConsumer.receive()`, `setTransactionTimeout(int)`

#### getReceiveTimeout

    protected long getReceiveTimeout()

Return the receive timeout (ms) configured for this listener container.

Since:
  4.2

#### initialize

    public void initialize()

Description copied from class: `AbstractJmsListeningContainer`
Initialize this container.

Creates a JMS Connection, starts the `Connection` (if `"autoStartup"` hasn't been turned off), and calls `AbstractJmsListeningContainer.doInitialize()`.

Overrides:
  `initialize` in class `AbstractJmsListeningContainer`

#### createListenerConsumer

    protected MessageConsumer createListenerConsumer(Session session)
                                              throws JMSException

Create a MessageConsumer for the given JMS Session, registering a MessageListener for the specified listener.

Parameters:
  `session` - the JMS Session to work on
Returns:
  the MessageConsumer
Throws:
  `JMSException` - if thrown by JMS methods
See Also:
  `receiveAndExecute(java.lang.Object, javax.jms.Session, javax.jms.MessageConsumer)`

#### receiveAndExecute

    protected boolean receiveAndExecute(Object invoker,
                                        @Nullable
                                        Session session,
                                        @Nullable
                                        MessageConsumer consumer)
                                 throws JMSException

Execute the listener for a message received from the given consumer, wrapping the entire operation in an external transaction if demanded.

Parameters:
  `session` - the JMS Session to work on
  `consumer` - the MessageConsumer to work on
Returns:
  whether a message has been received
Throws:
  `JMSException` - if thrown by JMS methods
See Also:
  `doReceiveAndExecute(java.lang.Object, javax.jms.Session, javax.jms.MessageConsumer, org.springframework.transaction.TransactionStatus)`

#### doReceiveAndExecute

    protected boolean doReceiveAndExecute(Object invoker,
                                          @Nullable
                                          Session session,
                                          @Nullable
                                          MessageConsumer consumer,
                                          @Nullable
                                          org.springframework.transaction.TransactionStatus status)
                                   throws JMSException

Actually execute the listener for a message received from the given consumer, fetching all requires resources and invoking the listener.

Parameters:
  `session` - the JMS Session to work on
  `consumer` - the MessageConsumer to work on
  `status` - the TransactionStatus (may be `null`)
Returns:
  whether a message has been received
Throws:
  `JMSException` - if thrown by JMS methods
See Also:
  `AbstractMessageListenerContainer.doExecuteListener(javax.jms.Session, javax.jms.Message)`

#### isSessionLocallyTransacted

    protected boolean isSessionLocallyTransacted(Session session)

This implementation checks whether the Session is externally synchronized. In this case, the Session is not locally transacted, despite the listener container's "sessionTransacted" flag being set to "true".

Overrides:
  `isSessionLocallyTransacted` in class `AbstractMessageListenerContainer`
Parameters:
  `session` - the Session to check
Returns:
  whether the given Session is locally transacted
See Also:
  `JmsResourceHolder`

#### shouldCommitAfterNoMessageReceived

    protected boolean shouldCommitAfterNoMessageReceived(Session session)

Determine whether to trigger a commit after no message has been received. This is a good idea on any modern-day JMS provider.

Parameters:
  `session` - the current JMS Session which received no message
Returns:
  whether to call `AbstractMessageListenerContainer.commitIfNecessary(javax.jms.Session, javax.jms.Message)` on the given Session

#### receiveMessage

    @Nullable
    protected Message receiveMessage(MessageConsumer consumer)
                                        throws JMSException

Receive a message from the given consumer.

Parameters:
  `consumer` - the MessageConsumer to use
Returns:
  the Message, or `null` if none
Throws:
  `JMSException` - if thrown by JMS methods

#### messageReceived

    protected void messageReceived(Object invoker,
                                   Session session)

Template method that gets called right when a new message has been received, before attempting to process it. Allows subclasses to react to the event of an actual incoming message, for example adapting their consumer count.

Parameters:
  `invoker` - the invoker object (passed through)
  `session` - the receiving JMS Session

#### noMessageReceived

    protected void noMessageReceived(Object invoker,
                                     Session session)

Template method that gets called when no message has been received, before returning to the receive loop again. Allows subclasses to react to the event of no incoming message, for example marking the invoker as idle.

Parameters:
  `invoker` - the invoker object (passed through)
  `session` - the receiving JMS Session

#### getConnection

    @Nullable
    protected Connection getConnection(JmsResourceHolder holder)

Fetch an appropriate Connection from the given JmsResourceHolder.

This implementation accepts any JMS 1.1 Connection.

Parameters:
  `holder` - the JmsResourceHolder
Returns:
  an appropriate Connection fetched from the holder, or `null` if none found

#### getSession

    @Nullable
    protected Session getSession(JmsResourceHolder holder)

Fetch an appropriate Session from the given JmsResourceHolder.

This implementation accepts any JMS 1.1 Session.

Parameters:
  `holder` - the JmsResourceHolder
Returns:
  an appropriate Session fetched from the holder, or `null` if none found