I'm using JMS with GlassFish application server v2, and Spring 2.5.5. I want to read JMS messages with concurrent consumers, so I use the DefaultMessageListenerContainer, but I have some errors on the console (althougn the consumption of messages works fine):
Code:
endTransaction (XA) on JMSService:jmsdirect failed for connectionId:6762471324442619392 and flags=67108864 due to unkown JMSService server error.
RAR5031 : Exception système.
javax.transaction.SystemException
        at com.sun.jts.jta.TransactionImpl.delistResource(TransactionImpl.java:250)
        at com.sun.enterprise.distributedtx.J2EETransaction.delistResource(J2EETransaction.java:548)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.delistResource(J2EETransactionManagerImpl.java:833)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.delistResource(J2EETransactionManagerOpt.java:229)
        at com.sun.enterprise.resource.ResourceManagerImpl.unregisterResource(ResourceManagerImpl.java:265)
        at com.sun.enterprise.resource.ResourceManagerImpl.delistResource(ResourceManagerImpl.java:223)
        at com.sun.enterprise.resource.PoolManagerImpl.resourceClosed(PoolManagerImpl.java:400)
        at com.sun.enterprise.resource.ConnectorAllocator$ConnectionListenerImpl.connectionClosed(ConnectorAllocator.java:72)
        at com.sun.messaging.jms.ra.ConnectionEventListener.sendEvent(ConnectionEventListener.java:143)
        at com.sun.messaging.jms.ra.ManagedConnection.sendEvent(ManagedConnection.java:675)
        at com.sun.messaging.jms.ra.DirectConnection.close(DirectConnection.java:231)
        at org.springframework.jms.connection.ConnectionFactoryUtils.releaseConnection(ConnectionFactoryUtils.java:81)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:357)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:240)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:944)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:868)
        at java.lang.Thread.run(Thread.java:619)

I found a workaround to remove these errors: I set the transactionSynchronizationName property of the jtaTransactionManager to SYNCHRONIZATION_NEVER, and I modified the AbstractPollingMessageListenerContainer to commit the transaction before the call of ConnectionFactoryUtils.releaseConnection (I removed the transactionManager.commit statement from the receiveAndExecute method, and I put it before the 2 return statements of the method doReceiveAndExecute).
But I hope there is a better solution, I wonder if I misconfigured something.

I have an other problem: on my MessageListener, I rollback the transaction by using transactionManager.rollback(transaction); but if I use transaction.setRollbackOnly(); the transaction is not rollbacked. I want to use this method to avoid these errors:
Code:
[jmsContainer-3] ERROR DefaultMessageListenerContainer - Listener exception overridden by rollback exception
org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException
        at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1031)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:330)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:227)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:932)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:856)
        at java.lang.Thread.run(Thread.java:619)
Caused by: javax.transaction.RollbackException
        at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:311)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.commit(J2EETransactionManagerImpl.java:1030)
        at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:397)
        at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:197)
        at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1028)
        ... 7 more
Here is my configuration:
HTML Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <!--ConnectionFactory and queue.-->
    <bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate"/>
        </property>
        <property name="jndiName">
            <value>jms/myQueueConnectionFactory</value>
        </property>
    </bean>
    <bean id="queue" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
            <ref bean="jndiTemplate"/>
        </property>
        <property name="jndiName">
            <value>myQueue</value>
        </property>
    </bean>
    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"/>
    <!--Listener-->
    <bean id="messageListener" class="testjmsreceiver.MessageListenerConsumer">
        <constructor-arg>
            <ref bean="jtaTransactionManager"/>
        </constructor-arg>
    </bean>
    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
        <property name="destination" ref="queue"/>
        <property name="messageListener" ref="messageListener" />
        <property name="concurrentConsumers" value="2" />
        <property name="maxConcurrentConsumers" value="2" />
        <property name="transactionManager" ref="jtaTransactionManager" />
    </bean>
    <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionSynchronizationName" value="SYNCHRONIZATION_NEVER"/>
    </bean>
</beans>
and my MessageListener:
PHP Code:
package testjmsreceiver;
import java.util.Random;
import javax.jms.*;
import org.slf4j.*;
import org.springframework.transaction.PlatformTransactionManager;
public class 
MessageListenerConsumer implements MessageListener {
    static final 
Logger logger LoggerFactory.getLogger(MessageListenerConsumer.class);
    private final 
PlatformTransactionManager transactionManager;
    public 
MessageListenerConsumer(PlatformTransactionManager transactionManager) {
        
this.transactionManager transactionManager;
    }
    public 
void onMessage(Message msg) {
        try {
            
TextMessage message = (TextMessagemsg;
            
String text message.getText();
            
int sleepTime = new Random().nextInt(25000);
            
logger.info("Received message {}. Sleeping {}s"textsleepTime 1000);
            
Thread.sleep(sleepTime);
            if (new 
Random().nextInt(5) == 0) {
                
logger.info("Message {}: rollback"text);
                
transactionManager.rollback(transactionManager.getTransaction(null));
//                transactionManager.getTransaction(null).setRollbackOnly();//Does not work
            
} else {
                
logger.info("Message {}: commit"text);
            }
        } catch (
Exception ex) {
            
logger.error("error"ex);
        }
    }