Java Code Examples for org.springframework.jms.support.JmsUtils#closeSession()

The following examples show how to use org.springframework.jms.support.JmsUtils#closeSession() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SimpleMessageListenerContainer.java    From spring-analysis-note with MIT License 6 votes vote down vote up
/**
 * Destroy the registered JMS Sessions and associated MessageConsumers.
 */
@Override
protected void doShutdown() throws JMSException {
	synchronized (this.consumersMonitor) {
		if (this.consumers != null) {
			logger.debug("Closing JMS MessageConsumers");
			for (MessageConsumer consumer : this.consumers) {
				JmsUtils.closeMessageConsumer(consumer);
			}
			if (this.sessions != null) {
				logger.debug("Closing JMS Sessions");
				for (Session session : this.sessions) {
					JmsUtils.closeSession(session);
				}
			}
		}
	}
}
 
Example 2
Source File: JmsTemplate.java    From spring4-understanding with Apache License 2.0 6 votes vote down vote up
/**
 * A variant of {@link #execute(SessionCallback, boolean)} that explicitly
 * creates a non-transactional {@link Session}. The given {@link SessionCallback}
 * does not participate in an existing transaction.
 */
private <T> T executeLocal(SessionCallback<T> action, boolean startConnection) throws JmsException {
	Assert.notNull(action, "Callback object must not be null");
	Connection con = null;
	Session session = null;
	try {
		con = getConnectionFactory().createConnection();
		session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
		if (startConnection) {
			con.start();
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Executing callback on JMS Session: " + session);
		}
		return action.doInJms(session);
	}
	catch (JMSException ex) {
		throw convertJmsAccessException(ex);
	}
	finally {
		JmsUtils.closeSession(session);
		ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), startConnection);
	}
}
 
Example 3
Source File: JmsInvokerClientInterceptor.java    From spring4-understanding with Apache License 2.0 6 votes vote down vote up
/**
 * Execute the given remote invocation, sending an invoker request message
 * to this accessor's target queue and waiting for a corresponding response.
 * @param invocation the RemoteInvocation to execute
 * @return the RemoteInvocationResult object
 * @throws JMSException in case of JMS failure
 * @see #doExecuteRequest
 */
protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws JMSException {
	Connection con = createConnection();
	Session session = null;
	try {
		session = createSession(con);
		Queue queueToUse = resolveQueue(session);
		Message requestMessage = createRequestMessage(session, invocation);
		con.start();
		Message responseMessage = doExecuteRequest(session, queueToUse, requestMessage);
		if (responseMessage != null) {
			return extractInvocationResult(responseMessage);
		}
		else {
			return onReceiveTimeout(invocation);
		}
	}
	finally {
		JmsUtils.closeSession(session);
		ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), true);
	}
}
 
Example 4
Source File: SimpleMessageListenerContainer.java    From spring4-understanding with Apache License 2.0 6 votes vote down vote up
/**
 * Destroy the registered JMS Sessions and associated MessageConsumers.
 */
@Override
protected void doShutdown() throws JMSException {
	synchronized (this.consumersMonitor) {
		if (this.consumers != null) {
			logger.debug("Closing JMS MessageConsumers");
			for (MessageConsumer consumer : this.consumers) {
				JmsUtils.closeMessageConsumer(consumer);
			}
			logger.debug("Closing JMS Sessions");
			for (Session session : this.sessions) {
				JmsUtils.closeSession(session);
			}
		}
	}
}
 
Example 5
Source File: DefaultMessageListenerContainer.java    From spring4-understanding with Apache License 2.0 6 votes vote down vote up
private void clearResources() {
	if (sharedConnectionEnabled()) {
		synchronized (sharedConnectionMonitor) {
			JmsUtils.closeMessageConsumer(this.consumer);
			JmsUtils.closeSession(this.session);
		}
	}
	else {
		JmsUtils.closeMessageConsumer(this.consumer);
		JmsUtils.closeSession(this.session);
	}
	if (this.consumer != null) {
		synchronized (lifecycleMonitor) {
			registeredWithDestination--;
		}
	}
	this.consumer = null;
	this.session = null;
}
 
Example 6
Source File: JmsTemplate.java    From java-technology-stack with MIT License 6 votes vote down vote up
/**
 * A variant of {@link #execute(SessionCallback, boolean)} that explicitly
 * creates a non-transactional {@link Session}. The given {@link SessionCallback}
 * does not participate in an existing transaction.
 */
@Nullable
private <T> T executeLocal(SessionCallback<T> action, boolean startConnection) throws JmsException {
	Assert.notNull(action, "Callback object must not be null");
	Connection con = null;
	Session session = null;
	try {
		con = createConnection();
		session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
		if (startConnection) {
			con.start();
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Executing callback on JMS Session: " + session);
		}
		return action.doInJms(session);
	}
	catch (JMSException ex) {
		throw convertJmsAccessException(ex);
	}
	finally {
		JmsUtils.closeSession(session);
		ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), startConnection);
	}
}
 
Example 7
Source File: JmsInvokerClientInterceptor.java    From java-technology-stack with MIT License 6 votes vote down vote up
/**
 * Execute the given remote invocation, sending an invoker request message
 * to this accessor's target queue and waiting for a corresponding response.
 * @param invocation the RemoteInvocation to execute
 * @return the RemoteInvocationResult object
 * @throws JMSException in case of JMS failure
 * @see #doExecuteRequest
 */
protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws JMSException {
	Connection con = createConnection();
	Session session = null;
	try {
		session = createSession(con);
		Queue queueToUse = resolveQueue(session);
		Message requestMessage = createRequestMessage(session, invocation);
		con.start();
		Message responseMessage = doExecuteRequest(session, queueToUse, requestMessage);
		if (responseMessage != null) {
			return extractInvocationResult(responseMessage);
		}
		else {
			return onReceiveTimeout(invocation);
		}
	}
	finally {
		JmsUtils.closeSession(session);
		ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), true);
	}
}
 
Example 8
Source File: SimpleMessageListenerContainer.java    From java-technology-stack with MIT License 6 votes vote down vote up
/**
 * Destroy the registered JMS Sessions and associated MessageConsumers.
 */
@Override
protected void doShutdown() throws JMSException {
	synchronized (this.consumersMonitor) {
		if (this.consumers != null) {
			logger.debug("Closing JMS MessageConsumers");
			for (MessageConsumer consumer : this.consumers) {
				JmsUtils.closeMessageConsumer(consumer);
			}
			if (this.sessions != null) {
				logger.debug("Closing JMS Sessions");
				for (Session session : this.sessions) {
					JmsUtils.closeSession(session);
				}
			}
		}
	}
}
 
Example 9
Source File: DefaultMessageListenerContainer.java    From java-technology-stack with MIT License 6 votes vote down vote up
private void clearResources() {
	if (sharedConnectionEnabled()) {
		synchronized (sharedConnectionMonitor) {
			JmsUtils.closeMessageConsumer(this.consumer);
			JmsUtils.closeSession(this.session);
		}
	}
	else {
		JmsUtils.closeMessageConsumer(this.consumer);
		JmsUtils.closeSession(this.session);
	}
	if (this.consumer != null) {
		synchronized (lifecycleMonitor) {
			registeredWithDestination--;
		}
	}
	this.consumer = null;
	this.session = null;
}
 
Example 10
Source File: JmsTemplate.java    From spring-analysis-note with MIT License 6 votes vote down vote up
/**
 * A variant of {@link #execute(SessionCallback, boolean)} that explicitly
 * creates a non-transactional {@link Session}. The given {@link SessionCallback}
 * does not participate in an existing transaction.
 */
@Nullable
private <T> T executeLocal(SessionCallback<T> action, boolean startConnection) throws JmsException {
	Assert.notNull(action, "Callback object must not be null");
	Connection con = null;
	Session session = null;
	try {
		con = createConnection();
		session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
		if (startConnection) {
			con.start();
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Executing callback on JMS Session: " + session);
		}
		return action.doInJms(session);
	}
	catch (JMSException ex) {
		throw convertJmsAccessException(ex);
	}
	finally {
		JmsUtils.closeSession(session);
		ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), startConnection);
	}
}
 
Example 11
Source File: JmsInvokerClientInterceptor.java    From spring-analysis-note with MIT License 6 votes vote down vote up
/**
 * Execute the given remote invocation, sending an invoker request message
 * to this accessor's target queue and waiting for a corresponding response.
 * @param invocation the RemoteInvocation to execute
 * @return the RemoteInvocationResult object
 * @throws JMSException in case of JMS failure
 * @see #doExecuteRequest
 */
protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws JMSException {
	Connection con = createConnection();
	Session session = null;
	try {
		session = createSession(con);
		Queue queueToUse = resolveQueue(session);
		Message requestMessage = createRequestMessage(session, invocation);
		con.start();
		Message responseMessage = doExecuteRequest(session, queueToUse, requestMessage);
		if (responseMessage != null) {
			return extractInvocationResult(responseMessage);
		}
		else {
			return onReceiveTimeout(invocation);
		}
	}
	finally {
		JmsUtils.closeSession(session);
		ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), true);
	}
}
 
Example 12
Source File: DefaultMessageListenerContainer.java    From spring-analysis-note with MIT License 6 votes vote down vote up
private void clearResources() {
	if (sharedConnectionEnabled()) {
		synchronized (sharedConnectionMonitor) {
			JmsUtils.closeMessageConsumer(this.consumer);
			JmsUtils.closeSession(this.session);
		}
	}
	else {
		JmsUtils.closeMessageConsumer(this.consumer);
		JmsUtils.closeSession(this.session);
	}
	if (this.consumer != null) {
		synchronized (lifecycleMonitor) {
			registeredWithDestination--;
		}
	}
	this.consumer = null;
	this.session = null;
}
 
Example 13
Source File: AbstractMessageListenerContainer.java    From java-technology-stack with MIT License 5 votes vote down vote up
/**
 * Invoke the specified listener as Spring SessionAwareMessageListener,
 * exposing a new JMS Session (potentially with its own transaction)
 * to the listener if demanded.
 * @param listener the Spring SessionAwareMessageListener to invoke
 * @param session the JMS Session to operate on
 * @param message the received JMS Message
 * @throws JMSException if thrown by JMS API methods
 * @see SessionAwareMessageListener
 * @see #setExposeListenerSession
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void doInvokeListener(SessionAwareMessageListener listener, Session session, Message message)
		throws JMSException {

	Connection conToClose = null;
	Session sessionToClose = null;
	try {
		Session sessionToUse = session;
		if (!isExposeListenerSession()) {
			// We need to expose a separate Session.
			conToClose = createConnection();
			sessionToClose = createSession(conToClose);
			sessionToUse = sessionToClose;
		}
		// Actually invoke the message listener...
		listener.onMessage(message, sessionToUse);
		// Clean up specially exposed Session, if any.
		if (sessionToUse != session) {
			if (sessionToUse.getTransacted() && isSessionLocallyTransacted(sessionToUse)) {
				// Transacted session created by this container -> commit.
				JmsUtils.commitIfNecessary(sessionToUse);
			}
		}
	}
	finally {
		JmsUtils.closeSession(sessionToClose);
		JmsUtils.closeConnection(conToClose);
	}
}
 
Example 14
Source File: JmsTemplate.java    From java-technology-stack with MIT License 5 votes vote down vote up
/**
 * Execute the action specified by the given action object within a
 * JMS Session. Generalized version of {@code execute(SessionCallback)},
 * allowing the JMS Connection to be started on the fly.
 * <p>Use {@code execute(SessionCallback)} for the general case.
 * Starting the JMS Connection is just necessary for receiving messages,
 * which is preferably achieved through the {@code receive} methods.
 * @param action callback object that exposes the Session
 * @param startConnection whether to start the Connection
 * @return the result object from working with the Session
 * @throws JmsException if there is any problem
 * @see #execute(SessionCallback)
 * @see #receive
 */
@Nullable
public <T> T execute(SessionCallback<T> action, boolean startConnection) throws JmsException {
	Assert.notNull(action, "Callback object must not be null");
	Connection conToClose = null;
	Session sessionToClose = null;
	try {
		Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(
				obtainConnectionFactory(), this.transactionalResourceFactory, startConnection);
		if (sessionToUse == null) {
			conToClose = createConnection();
			sessionToClose = createSession(conToClose);
			if (startConnection) {
				conToClose.start();
			}
			sessionToUse = sessionToClose;
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Executing callback on JMS Session: " + sessionToUse);
		}
		return action.doInJms(sessionToUse);
	}
	catch (JMSException ex) {
		throw convertJmsAccessException(ex);
	}
	finally {
		JmsUtils.closeSession(sessionToClose);
		ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
	}
}
 
Example 15
Source File: JmsTemplate.java    From spring-analysis-note with MIT License 5 votes vote down vote up
/**
 * Execute the action specified by the given action object within a
 * JMS Session. Generalized version of {@code execute(SessionCallback)},
 * allowing the JMS Connection to be started on the fly.
 * <p>Use {@code execute(SessionCallback)} for the general case.
 * Starting the JMS Connection is just necessary for receiving messages,
 * which is preferably achieved through the {@code receive} methods.
 * @param action callback object that exposes the Session
 * @param startConnection whether to start the Connection
 * @return the result object from working with the Session
 * @throws JmsException if there is any problem
 * @see #execute(SessionCallback)
 * @see #receive
 */
@Nullable
public <T> T execute(SessionCallback<T> action, boolean startConnection) throws JmsException {
	Assert.notNull(action, "Callback object must not be null");
	Connection conToClose = null;
	Session sessionToClose = null;
	try {
		Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(
				obtainConnectionFactory(), this.transactionalResourceFactory, startConnection);
		if (sessionToUse == null) {
			conToClose = createConnection();
			sessionToClose = createSession(conToClose);
			if (startConnection) {
				conToClose.start();
			}
			sessionToUse = sessionToClose;
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Executing callback on JMS Session: " + sessionToUse);
		}
		return action.doInJms(sessionToUse);
	}
	catch (JMSException ex) {
		throw convertJmsAccessException(ex);
	}
	finally {
		JmsUtils.closeSession(sessionToClose);
		ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
	}
}
 
Example 16
Source File: AbstractMessageListenerContainer.java    From spring-analysis-note with MIT License 5 votes vote down vote up
/**
 * Invoke the specified listener as Spring SessionAwareMessageListener,
 * exposing a new JMS Session (potentially with its own transaction)
 * to the listener if demanded.
 * @param listener the Spring SessionAwareMessageListener to invoke
 * @param session the JMS Session to operate on
 * @param message the received JMS Message
 * @throws JMSException if thrown by JMS API methods
 * @see SessionAwareMessageListener
 * @see #setExposeListenerSession
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void doInvokeListener(SessionAwareMessageListener listener, Session session, Message message)
		throws JMSException {

	Connection conToClose = null;
	Session sessionToClose = null;
	try {
		Session sessionToUse = session;
		if (!isExposeListenerSession()) {
			// We need to expose a separate Session.
			conToClose = createConnection();
			sessionToClose = createSession(conToClose);
			sessionToUse = sessionToClose;
		}
		// Actually invoke the message listener...
		listener.onMessage(message, sessionToUse);
		// Clean up specially exposed Session, if any.
		if (sessionToUse != session) {
			if (sessionToUse.getTransacted() && isSessionLocallyTransacted(sessionToUse)) {
				// Transacted session created by this container -> commit.
				JmsUtils.commitIfNecessary(sessionToUse);
			}
		}
	}
	finally {
		JmsUtils.closeSession(sessionToClose);
		JmsUtils.closeConnection(conToClose);
	}
}
 
Example 17
Source File: AbstractMessageListenerContainer.java    From spring4-understanding with Apache License 2.0 5 votes vote down vote up
/**
 * Invoke the specified listener as Spring SessionAwareMessageListener,
 * exposing a new JMS Session (potentially with its own transaction)
 * to the listener if demanded.
 * @param listener the Spring SessionAwareMessageListener to invoke
 * @param session the JMS Session to operate on
 * @param message the received JMS Message
 * @throws JMSException if thrown by JMS API methods
 * @see SessionAwareMessageListener
 * @see #setExposeListenerSession
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void doInvokeListener(SessionAwareMessageListener listener, Session session, Message message)
		throws JMSException {

	Connection conToClose = null;
	Session sessionToClose = null;
	try {
		Session sessionToUse = session;
		if (!isExposeListenerSession()) {
			// We need to expose a separate Session.
			conToClose = createConnection();
			sessionToClose = createSession(conToClose);
			sessionToUse = sessionToClose;
		}
		// Actually invoke the message listener...
		listener.onMessage(message, sessionToUse);
		// Clean up specially exposed Session, if any.
		if (sessionToUse != session) {
			if (sessionToUse.getTransacted() && isSessionLocallyTransacted(sessionToUse)) {
				// Transacted session created by this container -> commit.
				JmsUtils.commitIfNecessary(sessionToUse);
			}
		}
	}
	finally {
		JmsUtils.closeSession(sessionToClose);
		JmsUtils.closeConnection(conToClose);
	}
}
 
Example 18
Source File: JmsTemplate.java    From spring4-understanding with Apache License 2.0 5 votes vote down vote up
/**
 * Execute the action specified by the given action object within a
 * JMS Session. Generalized version of {@code execute(SessionCallback)},
 * allowing the JMS Connection to be started on the fly.
 * <p>Use {@code execute(SessionCallback)} for the general case.
 * Starting the JMS Connection is just necessary for receiving messages,
 * which is preferably achieved through the {@code receive} methods.
 * @param action callback object that exposes the Session
 * @param startConnection whether to start the Connection
 * @return the result object from working with the Session
 * @throws JmsException if there is any problem
 * @see #execute(SessionCallback)
 * @see #receive
 */
public <T> T execute(SessionCallback<T> action, boolean startConnection) throws JmsException {
	Assert.notNull(action, "Callback object must not be null");
	Connection conToClose = null;
	Session sessionToClose = null;
	try {
		Session sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(
				getConnectionFactory(), this.transactionalResourceFactory, startConnection);
		if (sessionToUse == null) {
			conToClose = createConnection();
			sessionToClose = createSession(conToClose);
			if (startConnection) {
				conToClose.start();
			}
			sessionToUse = sessionToClose;
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Executing callback on JMS Session: " + sessionToUse);
		}
		return action.doInJms(sessionToUse);
	}
	catch (JMSException ex) {
		throw convertJmsAccessException(ex);
	}
	finally {
		JmsUtils.closeSession(sessionToClose);
		ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), startConnection);
	}
}
 
Example 19
Source File: AbstractPollingMessageListenerContainer.java    From java-technology-stack with MIT License 4 votes vote down vote up
/**
 * Actually execute the listener for a message received from the given consumer,
 * fetching all requires resources and invoking the listener.
 * @param session the JMS Session to work on
 * @param consumer the MessageConsumer to work on
 * @param status the TransactionStatus (may be {@code null})
 * @return whether a message has been received
 * @throws JMSException if thrown by JMS methods
 * @see #doExecuteListener(javax.jms.Session, javax.jms.Message)
 */
protected boolean doReceiveAndExecute(Object invoker, @Nullable Session session,
		@Nullable MessageConsumer consumer, @Nullable TransactionStatus status) throws JMSException {

	Connection conToClose = null;
	Session sessionToClose = null;
	MessageConsumer consumerToClose = null;
	try {
		Session sessionToUse = session;
		boolean transactional = false;
		if (sessionToUse == null) {
			sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(
					obtainConnectionFactory(), this.transactionalResourceFactory, true);
			transactional = (sessionToUse != null);
		}
		if (sessionToUse == null) {
			Connection conToUse;
			if (sharedConnectionEnabled()) {
				conToUse = getSharedConnection();
			}
			else {
				conToUse = createConnection();
				conToClose = conToUse;
				conToUse.start();
			}
			sessionToUse = createSession(conToUse);
			sessionToClose = sessionToUse;
		}
		MessageConsumer consumerToUse = consumer;
		if (consumerToUse == null) {
			consumerToUse = createListenerConsumer(sessionToUse);
			consumerToClose = consumerToUse;
		}
		Message message = receiveMessage(consumerToUse);
		if (message != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Received message of type [" + message.getClass() + "] from consumer [" +
						consumerToUse + "] of " + (transactional ? "transactional " : "") + "session [" +
						sessionToUse + "]");
			}
			messageReceived(invoker, sessionToUse);
			boolean exposeResource = (!transactional && isExposeListenerSession() &&
					!TransactionSynchronizationManager.hasResource(obtainConnectionFactory()));
			if (exposeResource) {
				TransactionSynchronizationManager.bindResource(
						obtainConnectionFactory(), new LocallyExposedJmsResourceHolder(sessionToUse));
			}
			try {
				doExecuteListener(sessionToUse, message);
			}
			catch (Throwable ex) {
				if (status != null) {
					if (logger.isDebugEnabled()) {
						logger.debug("Rolling back transaction because of listener exception thrown: " + ex);
					}
					status.setRollbackOnly();
				}
				handleListenerException(ex);
				// Rethrow JMSException to indicate an infrastructure problem
				// that may have to trigger recovery...
				if (ex instanceof JMSException) {
					throw (JMSException) ex;
				}
			}
			finally {
				if (exposeResource) {
					TransactionSynchronizationManager.unbindResource(obtainConnectionFactory());
				}
			}
			// Indicate that a message has been received.
			return true;
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Consumer [" + consumerToUse + "] of " + (transactional ? "transactional " : "") +
						"session [" + sessionToUse + "] did not receive a message");
			}
			noMessageReceived(invoker, sessionToUse);
			// Nevertheless call commit, in order to reset the transaction timeout (if any).
			if (shouldCommitAfterNoMessageReceived(sessionToUse)) {
				commitIfNecessary(sessionToUse, null);
			}
			// Indicate that no message has been received.
			return false;
		}
	}
	finally {
		JmsUtils.closeMessageConsumer(consumerToClose);
		JmsUtils.closeSession(sessionToClose);
		ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), true);
	}
}
 
Example 20
Source File: AbstractPollingMessageListenerContainer.java    From spring-analysis-note with MIT License 4 votes vote down vote up
/**
 * Actually execute the listener for a message received from the given consumer,
 * fetching all requires resources and invoking the listener.
 * @param session the JMS Session to work on
 * @param consumer the MessageConsumer to work on
 * @param status the TransactionStatus (may be {@code null})
 * @return whether a message has been received
 * @throws JMSException if thrown by JMS methods
 * @see #doExecuteListener(javax.jms.Session, javax.jms.Message)
 */
protected boolean doReceiveAndExecute(Object invoker, @Nullable Session session,
		@Nullable MessageConsumer consumer, @Nullable TransactionStatus status) throws JMSException {

	Connection conToClose = null;
	Session sessionToClose = null;
	MessageConsumer consumerToClose = null;
	try {
		Session sessionToUse = session;
		boolean transactional = false;
		if (sessionToUse == null) {
			sessionToUse = ConnectionFactoryUtils.doGetTransactionalSession(
					obtainConnectionFactory(), this.transactionalResourceFactory, true);
			transactional = (sessionToUse != null);
		}
		if (sessionToUse == null) {
			Connection conToUse;
			if (sharedConnectionEnabled()) {
				conToUse = getSharedConnection();
			}
			else {
				conToUse = createConnection();
				conToClose = conToUse;
				conToUse.start();
			}
			sessionToUse = createSession(conToUse);
			sessionToClose = sessionToUse;
		}
		MessageConsumer consumerToUse = consumer;
		if (consumerToUse == null) {
			consumerToUse = createListenerConsumer(sessionToUse);
			consumerToClose = consumerToUse;
		}
		Message message = receiveMessage(consumerToUse);
		if (message != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Received message of type [" + message.getClass() + "] from consumer [" +
						consumerToUse + "] of " + (transactional ? "transactional " : "") + "session [" +
						sessionToUse + "]");
			}
			messageReceived(invoker, sessionToUse);
			boolean exposeResource = (!transactional && isExposeListenerSession() &&
					!TransactionSynchronizationManager.hasResource(obtainConnectionFactory()));
			if (exposeResource) {
				TransactionSynchronizationManager.bindResource(
						obtainConnectionFactory(), new LocallyExposedJmsResourceHolder(sessionToUse));
			}
			try {
				doExecuteListener(sessionToUse, message);
			}
			catch (Throwable ex) {
				if (status != null) {
					if (logger.isDebugEnabled()) {
						logger.debug("Rolling back transaction because of listener exception thrown: " + ex);
					}
					status.setRollbackOnly();
				}
				handleListenerException(ex);
				// Rethrow JMSException to indicate an infrastructure problem
				// that may have to trigger recovery...
				if (ex instanceof JMSException) {
					throw (JMSException) ex;
				}
			}
			finally {
				if (exposeResource) {
					TransactionSynchronizationManager.unbindResource(obtainConnectionFactory());
				}
			}
			// Indicate that a message has been received.
			return true;
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("Consumer [" + consumerToUse + "] of " + (transactional ? "transactional " : "") +
						"session [" + sessionToUse + "] did not receive a message");
			}
			noMessageReceived(invoker, sessionToUse);
			// Nevertheless call commit, in order to reset the transaction timeout (if any).
			if (shouldCommitAfterNoMessageReceived(sessionToUse)) {
				commitIfNecessary(sessionToUse, null);
			}
			// Indicate that no message has been received.
			return false;
		}
	}
	finally {
		JmsUtils.closeMessageConsumer(consumerToClose);
		JmsUtils.closeSession(sessionToClose);
		ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), true);
	}
}