EJBコンテナー、Webコンテナー内で管理されたJMS接続から同時に複数のSessionを生成できない

以下の条件を満たすとJBoss Messaging + Spring MDPの環境で以下の例外となります。

  • java:/JmsXAからXA対応(JCAのリソースアダプター経由)の接続ファクトリを使用
  • concurrency属性を2以上に設定
  • cache属性をsession以上に設定
javax.jms.JMSException: Could not create a session: javax.jms.IllegalStateException: Only allowed one session per connection. See the J2EE spec, e.g. J2EE1.4 Section 6.6
	at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.allocateConnection(JmsSessionFactoryImpl.java:426)
	at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.createSession(JmsSessionFactoryImpl.java:374)
	at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:196)
	at org.springframework.jms.listener.DefaultMessageListenerContainer.access$12(DefaultMessageListenerContainer.java:1)
	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.initResourcesIfNecessary(DefaultMessageListenerContainer.java:1078)
	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1057)
	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:952)
	at org.springframework.jca.work.DelegatingWork.run(DelegatingWork.java:57)
	at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:205)
	at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:260)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)

実際にJavaEEの仕様書の6.6節には以下の記述があります。

Application components in the web and EJB containers must not attempt to create more than one active (not closed) Session object per connection. An attempt to use the Connection object’s createSession method when an active Session object exists for that connection should be prohibited by the container. The container may throw a JMSException if the application component violates this restriction. Application client containers must support the creation of multiple sessions for each connection.

つまり、EJBやWebコンテナー内のコンポーネントを同一のJMS接続から同時に複数のアクティブなSessionを作成できないということですね。(外部のクライアントの場合は逆に複数の接続を作成できなくてはならないようです。)
したがって、以下のXA対応の管理されたキューに対するJMS接続を使用する場合は以下のいずれかの設定にする必要があります。

<jms:listener-container 
		concurrency="1" 
		cache="consumer"
		... >


<jms:listener-container 
		concurrency="2以上" 
		cache="none"
		... >

ただし、通常トピックの場合は同時に同じメッセージを受信しても困るのと、subscriberは常にアクティブでないと受信漏れが発生するため、前者の設定しか取りえません。
なお、この問題はSpring固有の問題ではなくて、JavaEEの仕様の問題なのでSeamでも発生するケースがあるようです。rarファイルの設定により、JavaEEの仕様に厳密に従わずに複数のJMS Sessionの生成を可能にすることも可能なようです。
http://seamframework.org/Community/ManagedTopicPublisherJavaxjmsIllegalStateExceptionOnlyAllowedOneSessionPerConnection