[jboss-cvs] JBossAS SVN: r66692 - in branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364: ejb3 and 14 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Nov 2 15:44:42 EDT 2007


Author: bdecoste
Date: 2007-11-02 15:44:42 -0400 (Fri, 02 Nov 2007)
New Revision: 66692

Added:
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test-configs/mdbsessionpoolclear/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test-configs/mdbsessionpoolclear/deploy/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/ejb-jar.xml
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/jboss.xml
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/ra.xml
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/mdbtest-service.xml
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/Ejb21Mdb.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/Ejb3Mdb.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSession.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSessionPool.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSessionPoolFactory.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestStatus.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestStatusBean.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsBytesMessage.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionFactory.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionFactoryImpl.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionManager.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionMetaData.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionRequestInfo.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsCred.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsLocalTransaction.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMCFProperties.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsManagedConnection.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsManagedConnectionFactory.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMapMessage.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessage.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessageConsumer.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessageListener.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMetaData.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsObjectMessage.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsQueueReceiver.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsResourceAdapter.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSession.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSessionFactory.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSessionFactoryImpl.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsStreamMessage.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsTextMessage.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsTopicSubscriber.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/DLQHandler.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsActivation.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsActivationSpec.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsServerSession.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsServerSessionPool.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/AbstractDLQHandler.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/GenericDLQHandler.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/JBossMQDLQHandler.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/package.html
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/unit/
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/unit/MDBUnitTestCase.java
Modified:
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsActivationSpec.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSessionPool.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/build-test.xml
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/ejb/plugins/jms/JMSContainerInvoker.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/ejb/plugins/jms/JMSContainerInvokerMBean.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/ServerSessionPoolFactory.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSession.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSessionPool.java
   branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSessionPoolFactory.java
Log:
[JBPAPP-387] Tests and fixes for EJB2.1 and EJB3.0 MDB session pool failover - simulation of TIBCO EMS session behavior

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsActivationSpec.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsActivationSpec.java	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsActivationSpec.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -122,6 +122,42 @@
    
    private Boolean isSameRMOverrideValue;
    
+   private boolean forceClearOnShutdown = false;
+   
+   private long forceClearOnShutdownInterval = 1000;
+   
+   private int forceClearAttempts = 0;
+   
+   public void setForceClearOnShutdown(boolean forceClear)
+   {
+      this.forceClearOnShutdown = forceClear;
+   }   
+   
+   public boolean isForceClearOnShutdown()
+   {
+      return this.forceClearOnShutdown;
+   }
+   
+   public long getForceClearOnShutdownInterval()
+   {
+      return this.forceClearOnShutdownInterval;
+   }
+   
+   public void setForceClearOnShutdownInterval(long forceClearOnShutdownInterval)
+   {
+      this.forceClearOnShutdownInterval = forceClearOnShutdownInterval;
+   }
+   
+   public int getForceClearAttempts()
+   {
+      return forceClearAttempts;
+   }
+   
+   public void setForceClearAttempts(int forceClearAttempts)
+   {
+      this.forceClearAttempts = forceClearAttempts;
+   }
+   
    /**
     * @return the acknowledgeMode.
     */

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSessionPool.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSessionPool.java	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/connector/src/main/org/jboss/resource/adapter/jms/inflow/JmsServerSessionPool.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -222,15 +222,41 @@
          sessionCount -= serverSessions.size();
          serverSessions.clear();
 
-         // Wait for inuse sessions
-         while (sessionCount > 0)
-         {
-            try
+         if (activation.getActivationSpec().isForceClearOnShutdown())
+         {        
+            int attempts = 0;
+            int forceClearAttempts = activation.getActivationSpec().getForceClearAttempts();
+            long forceClearInterval = activation.getActivationSpec().getForceClearOnShutdownInterval();
+            
+            log.trace("Force clear behavior in effect. Waiting for " + forceClearInterval + " milliseconds for " + forceClearAttempts + " attempts.");
+            
+            while((sessionCount > 0) && (attempts < forceClearAttempts))
             {
-               serverSessions.wait();
+               try
+               {
+                  serverSessions.wait(forceClearInterval);
+                  log.trace("Clear attempt " + attempts); 
+                  ++attempts;               
+            
+               }catch(InterruptedException ignore)
+               {
+                  
+               }
+            
             }
-            catch (InterruptedException ignore)
+         }
+         else
+         {
+            // Wait for inuse sessions
+            while (sessionCount > 0)
             {
+               try
+               {
+                  serverSessions.wait();
+               }
+               catch (InterruptedException ignore)
+               {
+               }
             }
          }
       }

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/build-test.xml
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/build-test.xml	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/build-test.xml	2007-11-02 19:44:42 UTC (rev 66692)
@@ -192,6 +192,7 @@
       <path refid="jboss.messaging.classpath"/>
       <path refid="jboss.test.classpath"/>
       <path refid="jboss.ejb3.classpath"/>
+	  <path refid="jboss.jca.classpath"/>
       <!--path refid="jboss.webservice.classpath"/-->
    </path>
 
@@ -2425,7 +2426,56 @@
          </fileset>
       </jar>
    </target>
+	
+	<target name="mdbsessionpoolclear"
+      description="Builds all jar files."
+      depends="compile-classes">
 
+      <mkdir dir="${build.lib}"/>
+
+      <jar jarfile="${build.lib}/mdbsessionpoolclear-test.ejb3">
+         <fileset dir="${build.classes}">
+            <include name="org/jboss/ejb3/test/mdbsessionpoolclear/TestStatus*.class"/>
+			<include name="org/jboss/ejb3/test/mdbsessionpoolclear/Ejb3*.class"/>
+         </fileset>
+         <fileset dir="${resources}/test/mdbsessionpoolclear">
+            <include name="*.xml"/>
+         </fileset>
+      </jar>
+	
+	  <jar jarfile="${build.lib}/mdbsessionpoolclear-test.jar">
+         <fileset dir="${build.classes}">
+            <include name="org/jboss/ejb3/test/mdbsessionpoolclear/Ejb21*.class"/>
+	        <include name="org/jboss/ejb3/test/mdbsessionpoolclear/TestStatus.class"/>
+         </fileset>
+         <fileset dir="${resources}/test/mdbsessionpoolclear">
+            <include name="META-INF/ejb-jar.xml"/>
+	        <include name="META-INF/jboss.xml"/>
+         </fileset>
+      </jar>
+	
+	  <jar jarfile="${resources}/test-configs/mdbsessionpoolclear/lib/mdbsessionpoolclear.jar">
+         <fileset dir="${build.classes}">
+	        <include name="org/jboss/ejb3/test/mdbsessionpoolclear/TestServer*.class"/>
+         </fileset>
+      </jar>
+	
+	  <jar jarfile="${build.lib}/test-jms-ra.jar">
+         <fileset dir="${build.classes}">
+	        <include name="org/jboss/ejb3/test/mdbsessionpoolclear/adapter/**/*.class"/>
+         </fileset>
+      </jar>
+	
+	  <jar jarfile="${resources}/test-configs/mdbsessionpoolclear/deploy/jms/test-jms-ra.rar">
+         <fileset dir="${build.lib}">
+	        <include name="test-jms-ra.jar"/>
+         </fileset>
+	     <fileset dir="${resources}/test/mdbsessionpoolclear">
+            <include name="META-INF/ra.xml"/>
+         </fileset>
+      </jar>
+   </target>
+
    <target name="mdb"
       description="Builds all jar files."
       depends="compile-classes">
@@ -3332,7 +3382,7 @@
 	  </copy>
    </target>
    
-   <target name="jars" depends="removedislocal, statelesscreation, defaultremotebindings, localfromremote, clusteredjms, entityoptimisticlocking, concurrentnaming, propertyreplacement, persistenceunits, invalidtxmdb, descriptortypo, libdeployment, homeinterface, timestampentity, servicexmbean, arjuna, mdbtransactions, unauthenticatedprincipal, clusteredservice, invoker, classloader, 
+   <target name="jars" depends="mdbsessionpoolclear, removedislocal, statelesscreation, defaultremotebindings, localfromremote, clusteredjms, entityoptimisticlocking, concurrentnaming, propertyreplacement, persistenceunits, invalidtxmdb, descriptortypo, libdeployment, homeinterface, timestampentity, servicexmbean, arjuna, mdbtransactions, unauthenticatedprincipal, clusteredservice, invoker, classloader, 
       circulardependency, jsp, timerdependency, servicedependency, servlet, stateless14, webservices, ear, ejbthree440, 
       ejbthree454, ejbthree653, ejbthree670, ejbthree712, ejbthree724, ejbthree751, ejbthree832, ejbthree921,
       ejbthree959, ejbthree963, ejbthree994,
@@ -3617,6 +3667,7 @@
 	  <antcall target="multi-instance-localfromremote-test"  inheritRefs="true"/>
 	  <antcall target="statelesscreation-test"  inheritRefs="true"/>
 	  <antcall target="removedislocal-test"  inheritRefs="true"/>
+	  <antcall target="mdbsessionpoolclear-test"  inheritRefs="true"/>
    </target>
 
    <target name="no-start-jboss-tests" depends="init" description="Execute all tests">
@@ -4046,6 +4097,26 @@
       <stop-jboss jboss.dist="${ejb3.dist}"/>
       <wait-on-shutdown conf="libdeployment"/>
    </target>
+	
+   <target name="mdbsessionpoolclear-test" depends="init">
+      <create-config baseconf="all" newconf="mdbsessionpoolclear" jboss.dist="${ejb3.dist}">
+         <patternset>
+            <include name="conf/**"/>
+            <include name="deploy*/**"/>
+            <include name="lib/**"/>
+         </patternset>
+      </create-config>
+     
+      <start-jboss conf="mdbsessionpoolclear" host="${node0}" jboss.dist="${ejb3.dist}" jvmargs="${ejb3.jboss.jvmargs}"/>
+      <wait-on-host/>
+      
+      <antcall target="test" inheritRefs="true">
+         <param name="test" value="mdbsessionpoolclear"/>
+      </antcall>
+      
+      <stop-jboss jboss.dist="${ejb3.dist}"/>
+      <wait-on-shutdown conf="mdbsessionpoolclear"/>
+   </target>
 
 
    <target name="ssl-simple-test" depends="init">

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/ejb-jar.xml
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/ejb-jar.xml	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/ejb-jar.xml	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_2_0.dtd">
+
+<ejb-jar>
+    <enterprise-beans>
+		<message-driven>
+			<ejb-name>Ejb21Mdb</ejb-name>
+				<ejb-class>org.jboss.ejb3.test.mdbsessionpoolclear.Ejb21Mdb</ejb-class>
+        		<message-selector></message-selector>
+         		<transaction-type>Bean</transaction-type>
+    			<acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
+        		<message-driven-destination>
+            		<destination-type>javax.jms.Queue</destination-type>
+					<subscription-durability>NonDurable</subscription-durability>
+        		</message-driven-destination>
+      	</message-driven>
+ 	</enterprise-beans>
+</ejb-jar>

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/jboss.xml
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/jboss.xml	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/jboss.xml	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE jboss PUBLIC
+      "-//JBoss//DTD JBOSS 3.2//EN"
+      "http://www.jboss.org/j2ee/dtd/jboss_3_2.dtd">
+<jboss>
+   <invoker-proxy-bindings>
+      <invoker-proxy-binding>
+         <name>my-message-driven-bean</name>
+         <invoker-mbean>default</invoker-mbean>
+         <proxy-factory>org.jboss.ejb.plugins.jms.JMSContainerInvoker</proxy-factory>
+         <proxy-factory-config>
+            <JMSProviderAdapterJNDI>DefaultJMSProvider</JMSProviderAdapterJNDI>
+            <ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI>
+            <MaximumSize>1</MaximumSize>
+            <MaxMessages>1</MaxMessages>
+            <ForceClearOnShutdown>true</ForceClearOnShutdown>
+            <ForceClearAttempts>5</ForceClearAttempts> 
+            <ForceClearInterval>500</ForceClearInterval>
+            <MDBConfig>
+               <ReconnectIntervalSec>10</ReconnectIntervalSec>
+               <DLQConfig>
+                  <DestinationQueue>queue/DLQ</DestinationQueue>
+                  <MaxTimesRedelivered>10</MaxTimesRedelivered>
+                  <TimeToLive>0</TimeToLive>
+               </DLQConfig>
+            </MDBConfig>
+         </proxy-factory-config>
+      </invoker-proxy-binding>
+   </invoker-proxy-bindings>
+
+   <enterprise-beans>
+      <message-driven>
+         <ejb-name>Ejb21Mdb</ejb-name>
+         <configuration-name>Standard Message Driven Bean</configuration-name>
+         <destination-jndi-name>queue/mdbsessionpoolclearQueue</destination-jndi-name>
+         <invoker-bindings>
+            <invoker>
+               <invoker-proxy-binding-name>my-message-driven-bean</invoker-proxy-binding-name>
+            </invoker>
+         </invoker-bindings>
+      </message-driven>
+   </enterprise-beans>
+</jboss>

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/ra.xml
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/ra.xml	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/META-INF/ra.xml	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- $Id: ra.xml 38347 2005-11-22 00:14:22Z adrian $ -->
+
+<connector xmlns="http://java.sun.com/xml/ns/j2ee"
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
+           http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
+           version="1.5">
+
+   <description>JBoss JMS Resource Adapter</description>
+   <display-name>JMS Adapter</display-name>
+
+   <vendor-name>JBoss, Inc</vendor-name>
+   <eis-type>JMS 1.1 Server</eis-type>
+   <resourceadapter-version>4.0</resourceadapter-version>
+
+   <license>
+      <description>
+ JBoss, Home of Professional Open Source
+ Copyright 2005, JBoss Inc., and individual contributors as indicated
+ by the @authors tag. See the copyright.txt in the distribution for a
+ full listing of individual contributors.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+      </description>
+      <license-required>true</license-required>
+   </license>
+
+   <resourceadapter>
+      <resourceadapter-class>org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.JmsResourceAdapter</resourceadapter-class>
+
+      <outbound-resourceadapter>
+         <connection-definition>
+            <managedconnectionfactory-class>org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.JmsManagedConnectionFactory</managedconnectionfactory-class>
+            <config-property>
+              <description>The jndi name of the provider of connection factories</description>
+              <config-property-name>JmsProviderAdapterJNDI</config-property-name>
+              <config-property-type>java.lang.String</config-property-type>
+              <config-property-value>java:DefaultJMSProvider</config-property-value>
+            </config-property>
+            <config-property>
+               <description>The default session type</description>
+               <config-property-name>SessionDefaultType</config-property-name>
+               <config-property-type>java.lang.String</config-property-type>
+               <config-property-value>javax.jms.Topic</config-property-value>
+            </config-property>
+            <config-property>
+              <description>The user name used to login to the jms server</description>
+              <config-property-name>UserName</config-property-name>
+              <config-property-type>java.lang.String</config-property-type>
+              <config-property-value></config-property-value>
+            </config-property>
+            <config-property>
+              <description>The password used to login to the jms server</description>
+              <config-property-name>Password</config-property-name>
+      	     <config-property-type>java.lang.String</config-property-type>
+      	     <config-property-value></config-property-value>
+            </config-property>
+            <config-property>
+              <description>The client id for this connection factory</description>
+              <config-property-name>ClientID</config-property-name>
+      	     <config-property-type>java.lang.String</config-property-type>
+      	     <config-property-value></config-property-value>
+            </config-property>
+            <config-property>
+              <config-property-name>Strict</config-property-name>
+	           <config-property-type>java.lang.Boolean</config-property-type>
+	           <config-property-value>true</config-property-value>
+            </config-property>
+            <connectionfactory-interface>org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.JmsConnectionFactory</connectionfactory-interface>
+            <connectionfactory-impl-class>org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.JmsConnectionFactoryImpl</connectionfactory-impl-class>
+            <connection-interface>javax.jms.Session</connection-interface>
+            <connection-impl-class>org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.JmsSession</connection-impl-class>
+         </connection-definition>
+         <transaction-support>XATransaction</transaction-support>
+         <authentication-mechanism>
+            <authentication-mechanism-type>BasicPassword</authentication-mechanism-type>
+            <credential-interface>javax.resource.spi.security.PasswordCredential</credential-interface>
+         </authentication-mechanism>
+         <reauthentication-support>false</reauthentication-support>
+      </outbound-resourceadapter>
+
+      <inbound-resourceadapter>
+         <messageadapter>        
+            <messagelistener>
+               <messagelistener-type>javax.jms.MessageListener</messagelistener-type>
+               <activationspec>
+                  <activationspec-class>org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.JmsActivationSpec</activationspec-class>
+                  <required-config-property>
+                      <config-property-name>destination</config-property-name>
+                  </required-config-property>
+                  <required-config-property>
+                      <config-property-name>destinationType</config-property-name>
+                  </required-config-property>
+               </activationspec>
+            </messagelistener>
+         </messageadapter>
+      </inbound-resourceadapter>
+
+   </resourceadapter>
+</connector>

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/mdbtest-service.xml
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/mdbtest-service.xml	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/resources/test/mdbsessionpoolclear/mdbtest-service.xml	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<server>
+   <mbean code="org.jboss.mq.server.jmx.Queue"
+      name="jboss.mq.destination:service=Queue,name=mdbsessionpoolclearQueue">
+      <attribute name="JNDIName">queue/mdbsessionpoolclearQueue</attribute>
+      <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
+   </mbean>
+   
+   <mbean code="org.jboss.mq.server.jmx.Queue"
+      name="jboss.mq.destination:service=Queue,name=ejb3mdbsessionpoolclearQueue">
+      <attribute name="JNDIName">queue/ejb3mdbsessionpoolclearQueue</attribute>
+      <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
+   </mbean>
+</server>

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/Ejb21Mdb.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/Ejb21Mdb.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/Ejb21Mdb.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear;
+
+import javax.ejb.MessageDrivenBean;
+import javax.ejb.MessageDrivenContext;
+import javax.ejb.EJBException;
+
+import javax.jms.MessageListener;
+import javax.jms.Message;
+import javax.jms.TextMessage;
+
+import javax.naming.InitialContext;
+
+import org.jboss.logging.Logger;
+
+/**
+ * MessageBeanImpl.java
+ *
+ *
+ * Created: Sat Nov 25 18:07:50 2000
+ *
+ * @author Peter Antman DN <peter.antman at dn.se>
+ * @version
+ */
+
+public class Ejb21Mdb implements MessageDrivenBean, MessageListener
+{
+   private static final Logger log = Logger.getLogger(Ejb21Mdb.class);
+   
+   private MessageDrivenContext ctx = null;
+    
+   public Ejb21Mdb()
+   {
+	
+   }
+   
+   public void setMessageDrivenContext(MessageDrivenContext ctx) throws EJBException
+   {
+      this.ctx = ctx;
+   }
+    
+   public void ejbCreate() {}
+
+   public void ejbRemove() {ctx=null;}
+
+   public void onMessage(Message message)
+   {
+      try
+      {
+         InitialContext jndiContext = new InitialContext();
+         TestStatus status = (TestStatus)jndiContext.lookup("TestStatusBean/remote");
+         int count = status.increment();
+         log.info("**** Ejb21Mdb got message " + count + " " + ((TextMessage)message).getText());
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+      }
+      
+   }
+} 
+
+

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/Ejb3Mdb.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/Ejb3Mdb.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/Ejb3Mdb.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear;
+
+import org.jboss.logging.Logger;
+import org.jboss.annotation.ejb.ResourceAdapter;
+
+import javax.ejb.EJB;
+import javax.ejb.MessageDriven;
+import javax.ejb.ActivationConfigProperty;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.TextMessage;
+
+/**
+ *
+ * @version <tt>$Revision: 60233 $</tt>
+ * @author <a href="mailto:bdecoste at jboss.com">William DeCoste</a>
+ */
+ at MessageDriven(activationConfig =
+{
+ at ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
+ at ActivationConfigProperty(propertyName="destination", propertyValue="queue/ejb3mdbsessionpoolclearQueue"),
+ at ActivationConfigProperty(propertyName="forceClearOnShutdown", propertyValue="true"),
+ at ActivationConfigProperty(propertyName="forceClearOnShutdownInterval", propertyValue="500"),
+ at ActivationConfigProperty(propertyName="forceClearAttempts", propertyValue="5"),
+ at ActivationConfigProperty(propertyName="maxSession", propertyValue="1")
+})
+ at ResourceAdapter("test-jms-ra.rar")
+public class Ejb3Mdb implements MessageListener
+{
+   private static final Logger log = Logger.getLogger(Ejb3Mdb.class);
+
+   @EJB TestStatus status;
+   
+   public void onMessage(Message message)
+   {
+      try
+      {
+         int count = status.increment();
+         log.info("**** Ejb3Mdb got message " + count + " " + ((TextMessage)message).getText());
+      }
+      catch (Exception e)
+      {
+         e.printStackTrace();
+      }
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSession.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSession.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSession.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear;
+
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageListener;
+import javax.jms.ServerSessionPool;
+import javax.jms.Session;
+import javax.jms.XASession;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.asf.StdServerSessionPool;
+import org.jboss.logging.Logger;
+import org.jboss.tm.XidFactoryMBean;
+
+
+public class TestServerSession extends org.jboss.jms.asf.StdServerSession
+{
+   private static final Logger log = Logger.getLogger(TestServerSession.class);
+   
+   public TestServerSession(final StdServerSessionPool pool,
+                           final Session session,
+                           final XASession xaSession,
+                           final MessageListener delegateListener,
+                           boolean useLocalTX,
+                           final XidFactoryMBean xidFactory,
+                           final TransactionManager tm)
+      throws JMSException
+   {
+      super(pool, session, xaSession, delegateListener, useLocalTX, xidFactory, tm);
+   }
+   
+   public void run()
+   {
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace("running...");
+      try
+      {
+         if (xaSession != null)
+            xaSession.run();
+         else
+            session.run();
+      }
+      finally
+      {
+         // don't recycle
+      }
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSessionPool.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSessionPool.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSessionPool.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,116 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageListener;
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.XAQueueConnection;
+import javax.jms.XAQueueSession;
+import javax.jms.XASession;
+import javax.jms.XATopicConnection;
+import javax.jms.XATopicSession;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.asf.StdServerSession;
+import org.jboss.logging.Logger;
+import org.jboss.tm.XidFactoryMBean;
+
+
+public class TestServerSessionPool extends org.jboss.jms.asf.StdServerSessionPool
+{
+   private static final Logger log = Logger.getLogger(TestServerSessionPool.class);
+   
+   public TestServerSessionPool(final Destination destination,
+                              final Connection con,
+                              final boolean transacted,
+                              final int ack,
+                              final boolean useLocalTX,
+                              final MessageListener listener,
+                              final int minSession,
+                              final int maxSession,
+                              final long keepAlive,
+                              final boolean forceClear,
+                              final long forceClearInterval,
+                              final int forceClearAttempts,
+                              final XidFactoryMBean xidFactory,
+                              final TransactionManager tm)
+      throws JMSException
+   {
+      super(destination, con, transacted, ack, useLocalTX, listener, minSession, maxSession, keepAlive, forceClear, forceClearInterval, forceClearAttempts, xidFactory, tm);
+   }
+   
+   protected void create() throws JMSException
+   {
+      for (int index = 0; index < poolSize; index++)
+      {
+         // Here is the meat, that MUST follow the spec
+         Session ses = null;
+         XASession xaSes = null;
+
+         log.debug("initializing with connection: " + con);
+
+         if (destination instanceof Topic && con instanceof XATopicConnection)
+         {
+            xaSes = ((XATopicConnection)con).createXATopicSession();
+            ses = ((XATopicSession)xaSes).getTopicSession();
+         }
+         else if (destination instanceof Queue && con instanceof XAQueueConnection)
+         {
+            xaSes = ((XAQueueConnection)con).createXAQueueSession();
+            ses = ((XAQueueSession)xaSes).getQueueSession();
+         }
+         else if (destination instanceof Topic && con instanceof TopicConnection)
+         {
+            ses = ((TopicConnection)con).createTopicSession(transacted, ack);
+            log.warn("Using a non-XA TopicConnection.  " +
+                  "It will not be able to participate in a Global UOW");
+         }
+         else if (destination instanceof Queue && con instanceof QueueConnection)
+         {
+            ses = ((QueueConnection)con).createQueueSession(transacted, ack);
+            log.warn("Using a non-XA QueueConnection.  " +
+                  "It will not be able to participate in a Global UOW");
+         }
+         else
+         {
+            throw new JMSException("Connection was not reconizable: " + con + " for destination " + destination);
+         }
+
+         // create the server session and add it to the pool - it is up to the
+         // server session to set the listener
+         StdServerSession serverSession = new TestServerSession(this, ses, xaSes,
+            listener, useLocalTX, xidFactory, tm);
+
+         sessionPool.add(serverSession);
+         numServerSessions++;
+
+         log.debug("added server session to the pool: " + serverSession);
+      }
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSessionPoolFactory.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSessionPoolFactory.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestServerSessionPoolFactory.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageListener;
+import javax.jms.ServerSessionPool;
+
+import org.jboss.jms.asf.StdServerSessionPool;
+import org.jboss.logging.Logger;
+
+public class TestServerSessionPoolFactory extends org.jboss.jms.asf.StdServerSessionPoolFactory
+{
+   private static final Logger log = Logger.getLogger(TestServerSessionPoolFactory.class);
+  
+   public ServerSessionPool getServerSessionPool(Destination destination, Connection con, int minSession, int maxSession, long keepAlive, boolean forceClear, long forceClearInterval, int forceClearAttempts, boolean isTransacted, int ack, boolean useLocalTX, MessageListener listener) throws JMSException
+   {
+      ServerSessionPool pool = new TestServerSessionPool(destination, con, isTransacted, ack, useLocalTX, listener, minSession, maxSession, keepAlive, forceClear, forceClearInterval, forceClearAttempts, xidFactory, transactionManager);
+      return pool;
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestStatus.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestStatus.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestStatus.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear;
+
+
+
+
+/**
+ * Comment
+ *
+ * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
+ * @version $Revision: 61798 $
+ */
+public interface TestStatus
+{
+   int queueFired();
+   
+   int increment();
+   
+   void clear();
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestStatusBean.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestStatusBean.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/TestStatusBean.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear;
+
+import javax.ejb.Stateless;
+import javax.ejb.Remote;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Comment
+ *
+ * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
+ * @version $Revision: 61798 $
+ */
+ at Stateless
+ at Remote(TestStatus.class)
+public class TestStatusBean implements TestStatus
+{
+   private static final Logger log = Logger.getLogger(TestStatusBean.class);
+   
+   public static int queueRan = 0;
+  
+   public int queueFired()
+   {
+      return queueRan;
+   }
+   
+   public int increment()
+   {
+      return ++queueRan;
+   }
+   
+   public void clear()
+   {
+      queueRan = 0;
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsBytesMessage.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsBytesMessage.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsBytesMessage.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,180 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+
+/**
+ * A wrapper for a message
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsBytesMessage extends JmsMessage implements BytesMessage
+{
+   /**
+    * Create a new wrapper
+    * 
+    * @param message the message
+    * @param session the session
+    */
+   public JmsBytesMessage(BytesMessage message, JmsSession session)
+   {
+      super(message, session);
+   }
+   
+   public long getBodyLength() throws JMSException
+   {
+      return ((BytesMessage) message).getBodyLength();
+   }
+   
+   public boolean readBoolean() throws JMSException
+   {
+      return ((BytesMessage) message).readBoolean();
+   }
+   
+   public byte readByte() throws JMSException
+   {
+      return ((BytesMessage) message).readByte();
+   }
+   
+   public int readBytes(byte[] value, int length) throws JMSException
+   {
+      return ((BytesMessage) message).readBytes(value, length);
+   }
+   
+   public int readBytes(byte[] value) throws JMSException
+   {
+      return ((BytesMessage) message).readBytes(value);
+   }
+   
+   public char readChar() throws JMSException
+   {
+      return ((BytesMessage) message).readChar();
+   }
+   
+   public double readDouble() throws JMSException
+   {
+      return ((BytesMessage) message).readDouble();
+   }
+   
+   public float readFloat() throws JMSException
+   {
+      return ((BytesMessage) message).readFloat();
+   }
+   
+   public int readInt() throws JMSException
+   {
+      return ((BytesMessage) message).readInt();
+   }
+   
+   public long readLong() throws JMSException
+   {
+      return ((BytesMessage) message).readLong();
+   }
+   
+   public short readShort() throws JMSException
+   {
+      return ((BytesMessage) message).readShort();
+   }
+   
+   public int readUnsignedByte() throws JMSException
+   {
+      return ((BytesMessage) message).readUnsignedByte();
+   }
+   
+   public int readUnsignedShort() throws JMSException
+   {
+      return ((BytesMessage) message).readUnsignedShort();
+   }
+   
+   public String readUTF() throws JMSException
+   {
+      return ((BytesMessage) message).readUTF();
+   }
+   
+   public void reset() throws JMSException
+   {
+      ((BytesMessage) message).reset();
+   }
+   
+   public void writeBoolean(boolean value) throws JMSException
+   {
+      ((BytesMessage) message).writeBoolean(value);
+   }
+   
+   public void writeByte(byte value) throws JMSException
+   {
+      ((BytesMessage) message).writeByte(value);
+   }
+   
+   public void writeBytes(byte[] value, int offset, int length) throws JMSException
+   {
+      ((BytesMessage) message).writeBytes(value, offset, length);
+   }
+   
+   public void writeBytes(byte[] value) throws JMSException
+   {
+      ((BytesMessage) message).writeBytes(value);
+   }
+   
+   public void writeChar(char value) throws JMSException
+   {
+      ((BytesMessage) message).writeChar(value);
+   }
+   
+   public void writeDouble(double value) throws JMSException
+   {
+      ((BytesMessage) message).writeDouble(value);
+   }
+   
+   public void writeFloat(float value) throws JMSException
+   {
+      ((BytesMessage) message).writeFloat(value);
+   }
+   
+   public void writeInt(int value) throws JMSException
+   {
+      ((BytesMessage) message).writeInt(value);
+   }
+   
+   public void writeLong(long value) throws JMSException
+   {
+      ((BytesMessage) message).writeLong(value);
+   }
+
+   public void writeObject(Object value) throws JMSException
+   {
+      ((BytesMessage) message).writeObject(value);
+   }
+
+   public void writeShort(short value) throws JMSException
+   {
+      ((BytesMessage) message).writeShort(value);
+   }
+
+   public void writeUTF(String value) throws JMSException
+   {
+      ((BytesMessage) message).writeUTF(value);
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionFactory.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionFactory.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionFactory.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.io.Serializable;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.TopicConnectionFactory;
+
+/**
+ * An aggregate interface for QueueConnectionFactory and
+ * TopicConnectionFactory.  Also marks as serializable.
+ *
+ * @author  <a href="mailto:peter.antman at tim.se">Peter Antman</a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version <pre>$Revision: 57189 $</pre>
+ */
+public interface JmsConnectionFactory 
+   extends ConnectionFactory,
+           TopicConnectionFactory,
+           QueueConnectionFactory,
+           Serializable
+{
+   int BOTH = 0;
+   int QUEUE = 1;
+   int TOPIC = 2;
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionFactoryImpl.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionFactoryImpl.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionFactoryImpl.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,168 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.QueueConnection;
+import javax.jms.TopicConnection;
+import javax.naming.Reference;
+import javax.resource.Referenceable;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ManagedConnectionFactory;
+
+import org.jboss.logging.Logger;
+
+/**
+ * The the connection factory implementation for the JMS RA.
+ *
+ * <p>
+ * This object will be the QueueConnectionFactory or TopicConnectionFactory
+ * which clients will use to create connections.
+ * 
+ * @author  <a href="mailto:peter.antman at tim.se">Peter Antman</a>.
+ * @author  <a href="mailto:jason at planet57.com">Jason Dillon</a>
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version <tt>$Revision: 57189 $</tt>
+ */
+public class JmsConnectionFactoryImpl 
+   implements JmsConnectionFactory, Referenceable
+{
+   private static final long serialVersionUID = -5135366013101194277L;
+
+   private static final Logger log = Logger.getLogger(JmsConnectionFactoryImpl.class);
+
+   private ManagedConnectionFactory mcf;
+
+   private ConnectionManager cm;
+
+   private Reference reference;
+
+   public JmsConnectionFactoryImpl(final ManagedConnectionFactory mcf,
+                                   final ConnectionManager cm) 
+   {
+      this.mcf = mcf;
+
+      boolean trace = log.isTraceEnabled();
+      if (cm == null)
+      {
+         // This is standalone usage, no appserver
+         this.cm = new JmsConnectionManager();
+         if (trace)
+            log.trace("Created new connection manager");
+      }
+      else
+         this.cm = cm;
+
+      if (trace)
+         log.trace("Using ManagedConnectionFactory=" + mcf + ", ConnectionManager=" + cm);
+   }
+
+   public void setReference(final Reference reference) 
+   {
+      this.reference = reference;
+
+      if (log.isTraceEnabled())
+         log.trace("Using Reference=" + reference);
+   }
+    
+   public Reference getReference() 
+   {
+      return reference;
+   }
+   
+   // --- QueueConnectionFactory
+   
+   public QueueConnection createQueueConnection() throws JMSException 
+   {
+      QueueConnection qc = new JmsSessionFactoryImpl(mcf, cm, QUEUE);
+
+      if (log.isTraceEnabled())
+         log.trace("Created queue connection: " + qc);
+      
+      return qc;
+   }
+   
+   public QueueConnection createQueueConnection(String userName, String password) 
+      throws JMSException 
+   {
+      JmsSessionFactoryImpl s = new JmsSessionFactoryImpl(mcf, cm, QUEUE);
+      s.setUserName(userName);
+      s.setPassword(password);
+
+      if (log.isTraceEnabled())
+         log.trace("Created queue connection: " + s);
+      
+      return s;
+   } 
+
+   // --- TopicConnectionFactory
+   
+   public TopicConnection createTopicConnection() throws JMSException 
+   {
+      TopicConnection tc = new JmsSessionFactoryImpl(mcf, cm, TOPIC);
+
+      if (log.isTraceEnabled())
+         log.trace("Created topic connection: " + tc);
+
+      return tc;
+   }
+   
+   public TopicConnection createTopicConnection(String userName, String password)
+      throws JMSException 
+   {
+      JmsSessionFactoryImpl s = new JmsSessionFactoryImpl(mcf, cm, TOPIC);
+      s.setUserName(userName);
+      s.setPassword(password);
+      
+      if (log.isTraceEnabled())
+         log.trace("Created topic connection: " + s);
+
+      return s;
+   }
+
+   // --- JMS 1.1
+   
+   public Connection createConnection()
+      throws JMSException 
+   {
+      Connection c = new JmsSessionFactoryImpl(mcf, cm, BOTH);
+
+      if (log.isTraceEnabled())
+         log.trace("Created connection: " + c);
+
+      return c;
+   }
+
+   public Connection createConnection(String userName, String password)
+      throws JMSException
+   {
+      JmsSessionFactoryImpl s = new JmsSessionFactoryImpl(mcf, cm, BOTH);
+      s.setUserName(userName);
+      s.setPassword(password);
+      
+      if (log.isTraceEnabled())
+         log.trace("Created connection: " + s);
+
+      return s;
+   }  
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionManager.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionManager.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionManager.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+
+import org.jboss.logging.Logger;
+
+/**
+ * The resource adapters own ConnectionManager, used in non-managed
+ * environments.
+ * 
+ * <p>Will handle some of the houskeeping an appserver nomaly does.
+ *
+ * @author <a href="mailto:peter.antman at tim.se">Peter Antman</a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsConnectionManager
+   implements ConnectionManager
+{
+   private static final long serialVersionUID = -3638293323045716739L;
+
+   private static final Logger log = Logger.getLogger(JmsConnectionManager.class);
+   
+   /**
+    * Construct a <tt>JmsConnectionManager</tt>.
+    */
+   public JmsConnectionManager() {
+      super();
+   }
+
+   /**
+    * Allocate a new connection.
+    *
+    * @param mcf
+    * @param cxRequestInfo
+    * @return                   A new connection
+    *
+    * @throws ResourceException Failed to create connection.
+    */
+   public Object allocateConnection(ManagedConnectionFactory mcf,
+                                    ConnectionRequestInfo cxRequestInfo) 
+      throws ResourceException
+   {
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace("Allocating connection; mcf=" + mcf + ", cxRequestInfo=" + cxRequestInfo);
+      
+      ManagedConnection mc = mcf.createManagedConnection(null, cxRequestInfo);
+      Object c = mc.getConnection(null, cxRequestInfo);
+
+      if (trace)
+         log.trace("Allocated connection: " + c + ", with managed connection: " + mc);
+      
+      return c;
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionMetaData.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionMetaData.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionMetaData.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,82 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.jms.ConnectionMetaData;
+
+/**
+ * This class implements javax.jms.ConnectionMetaData
+ * 
+ * @author Norbert Lataille (Norbert.Lataille at m4x.org)
+ * @author Hiram Chirino (Norbert.Lataille at m4x.org)
+ * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsConnectionMetaData implements ConnectionMetaData
+{
+   public String getJMSVersion()
+   {
+      return "1.1";
+   }
+
+   public int getJMSMajorVersion()
+   {
+      return 1;
+   }
+
+   public int getJMSMinorVersion()
+   {
+      return 1;
+   }
+
+   public String getJMSProviderName()
+   {
+      return "JBoss";
+   }
+
+   public String getProviderVersion()
+   {
+      return "4.0";
+   }
+
+   public int getProviderMajorVersion()
+   {
+      return 4;
+   }
+
+   public int getProviderMinorVersion()
+   {
+      return 0;
+   }
+
+   public Enumeration getJMSXPropertyNames()
+   {
+      Vector vector = new Vector();
+      vector.add("JMSXGroupID");
+      vector.add("JMSXGroupSeq");
+      vector.add("JMSXDeliveryCount");
+      return vector.elements();
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionRequestInfo.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionRequestInfo.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsConnectionRequestInfo.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,168 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.resource.spi.ConnectionRequestInfo;
+
+import javax.jms.Session;
+
+import org.jboss.util.Strings;
+
+/**
+ * Request information used in pooling
+ *
+ * @author <a href="mailto:peter.antman at tim.se">Peter Antman</a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsConnectionRequestInfo
+   implements ConnectionRequestInfo
+{
+   private String userName;
+   private String password;
+   private String clientID;
+
+   private boolean transacted = true;
+   private int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
+   private int type = JmsConnectionFactory.BOTH;
+
+   /**
+    * Creats with the MCF configured properties.
+    */
+   public JmsConnectionRequestInfo(JmsMCFProperties prop)
+   {
+      this.userName = prop.getUserName();
+      this.password = prop.getPassword();
+      this.clientID = prop.getClientID();
+      this.type = prop.getType();
+   }
+
+   /**
+    * Create with specified properties.
+    */
+   public JmsConnectionRequestInfo(final boolean transacted, 
+				   final int acknowledgeMode,
+				   final int type)
+   {
+      this.transacted = transacted;
+      this.acknowledgeMode = acknowledgeMode;
+      this.type = type;
+   }
+   
+   /**
+    * Fill in default values if missing. Only applies to user and password.
+    */
+   public void setDefaults(JmsMCFProperties prop)
+   {
+      if (userName == null)
+         userName = prop.getUserName();//May be null there to
+      if (password == null) 
+         password = prop.getPassword();//May be null there to
+      if (clientID == null) 
+         clientID = prop.getClientID();//May be null there to
+   }
+
+   public String getUserName() 
+   {
+      return userName;
+   }
+    
+   public void setUserName(String name) 
+   {
+      userName = name;
+   }
+
+   public String getPassword() 
+   {
+      return password;
+   }
+
+   public void setPassword(String password) 
+   {
+      this.password = password;
+   }
+
+   public String getClientID() 
+   {
+      return clientID;
+   }
+
+   public void setClientID(String clientID) 
+   {
+      this.clientID = clientID;
+   }
+
+   public boolean isTransacted()
+   {
+      return transacted;
+   }
+    
+   public int getAcknowledgeMode()
+   {
+      return acknowledgeMode;
+   }
+
+   public int getType()
+   {
+      return type;
+   }
+
+   public boolean equals(Object obj)
+   {
+      if (obj == null) return false;
+      if (obj instanceof JmsConnectionRequestInfo)
+      {
+         JmsConnectionRequestInfo you = (JmsConnectionRequestInfo) obj;
+         return (this.transacted == you.isTransacted() &&
+            this.acknowledgeMode == you.getAcknowledgeMode() &&
+            this.type == you.getType() &&
+            Strings.compare(userName, you.getUserName()) &&
+            Strings.compare(password, you.getPassword()) &&
+            Strings.compare(clientID, you.getClientID()));
+      }
+      else
+         return false;
+   }
+ 
+   public int hashCode()
+   {
+      int hashCode = 0;
+      if (transacted)
+         hashCode += 1;
+      if (type == JmsConnectionFactory.QUEUE)
+         hashCode += 3;
+      else if (type == JmsConnectionFactory.TOPIC)
+         hashCode += 5;
+      if (acknowledgeMode == Session.AUTO_ACKNOWLEDGE)
+         hashCode += 7;
+      else if (acknowledgeMode == Session.DUPS_OK_ACKNOWLEDGE)
+         hashCode += 11;
+      if (userName != null)
+         hashCode += userName.hashCode();
+      if (password != null)
+         hashCode += password.hashCode();
+      if (clientID != null)
+         hashCode += clientID.hashCode();
+      
+      return hashCode;
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsCred.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsCred.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsCred.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.util.Set;
+import java.util.Iterator;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.SecurityException;
+import javax.resource.spi.ConnectionRequestInfo;
+
+import javax.resource.spi.security.PasswordCredential;
+
+/**
+ * Credential information
+ * 
+ * @author <a href="mailto:peter.antman at tim.se">Peter Antman </a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsCred
+{
+	public String name;
+
+	public String pwd;
+
+	public JmsCred()
+	{
+		// empty
+	}
+
+	/**
+	 * Get our own simple cred
+	 */
+	public static JmsCred getJmsCred(ManagedConnectionFactory mcf, Subject subject, ConnectionRequestInfo info)
+			throws SecurityException
+	{
+		JmsCred jc = new JmsCred();
+		if (subject == null && info != null)
+		{
+			// Credentials specifyed on connection request
+			jc.name = ((JmsConnectionRequestInfo) info).getUserName();
+			jc.pwd = ((JmsConnectionRequestInfo) info).getPassword();
+		}
+		else if (subject != null)
+		{
+			// Credentials from appserver
+			PasswordCredential pwdc = GetCredentialAction.getCredential(subject, mcf);
+			if (pwdc == null)
+			{
+				// No hit - we do need creds
+				throw new SecurityException("No Password credentials found");
+			}
+			jc.name = pwdc.getUserName();
+			jc.pwd = new String(pwdc.getPassword());
+		}
+		else
+		{
+			throw new SecurityException("No Subject or ConnectionRequestInfo set, could not get credentials");
+		}
+		return jc;
+	}
+
+	public String toString()
+	{
+		return super.toString() + "{ username=" + name + ", password=**** }";
+	}
+
+   private static class GetCredentialAction implements PrivilegedAction
+   {
+      Subject subject;
+      ManagedConnectionFactory mcf;
+      GetCredentialAction(Subject subject, ManagedConnectionFactory mcf)
+      {
+         this.subject = subject;
+         this.mcf = mcf;
+      }
+      public Object run()
+      {
+         Set creds = subject.getPrivateCredentials(PasswordCredential.class);
+         PasswordCredential pwdc = null;
+         Iterator credentials = creds.iterator();
+         while (credentials.hasNext())
+         {
+            PasswordCredential curCred = (PasswordCredential) credentials.next();
+            if (curCred.getManagedConnectionFactory().equals(mcf))
+            {
+               pwdc = curCred;
+               break;
+            }
+         }
+         return pwdc;
+      }
+      static PasswordCredential getCredential(Subject subject, ManagedConnectionFactory mcf)
+      {
+         GetCredentialAction action = new GetCredentialAction(subject, mcf);
+         PasswordCredential pc = (PasswordCredential) AccessController.doPrivileged(action);
+         return pc;
+      }
+	}
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsLocalTransaction.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsLocalTransaction.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsLocalTransaction.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.JMSException;
+import javax.resource.ResourceException;
+import javax.resource.spi.LocalTransaction;
+
+import org.jboss.resource.JBossResourceException;
+
+/**
+ * JMS Local transaction
+ * 
+ * @author <a href="mailto:peter.antman at tim.se">Peter Antman </a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsLocalTransaction implements LocalTransaction
+{
+	protected JmsManagedConnection mc;
+
+	public JmsLocalTransaction(final JmsManagedConnection mc)
+	{
+		this.mc = mc;
+	}
+
+	public void begin() throws ResourceException
+	{
+	}
+
+	public void commit() throws ResourceException
+	{
+		try
+		{
+			if (mc.getSession().getTransacted())
+				mc.getSession().commit();
+		}
+		catch (JMSException e)
+		{
+			throw new JBossResourceException("Could not commit LocalTransaction", e);
+		}
+	}
+
+	public void rollback() throws ResourceException
+	{
+		try
+		{
+			if (mc.getSession().getTransacted())
+				mc.getSession().rollback();
+		}
+		catch (JMSException ex)
+		{
+			throw new JBossResourceException("Could not rollback LocalTransaction", ex);
+		}
+	}
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMCFProperties.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMCFProperties.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMCFProperties.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,192 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.Queue;
+import javax.jms.Topic;
+import javax.resource.ResourceException;
+
+import org.jboss.util.Strings;
+
+/**
+ * The MCF default properties, settable in ra.xml or in deployer.
+ *
+ * @author Peter Antman
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsMCFProperties
+   implements java.io.Serializable
+{
+   static final long serialVersionUID = -7997396849692340121L;
+
+   public static final String QUEUE_TYPE = Queue.class.getName();
+   public static final String TOPIC_TYPE = Topic.class.getName();
+
+   String userName;
+   String password;
+   String clientID;
+   String providerJNDI = "java:DefaultJMSProvider";
+   int type = JmsConnectionFactory.BOTH;
+   
+   public JmsMCFProperties()
+   {
+      // empty
+   }
+   
+   /**
+    * Set userName, null by default.
+    */
+   public void setUserName(final String userName)
+   {
+      this.userName = userName;
+   }
+
+   /**
+    * Get userName, may be null.
+    */ 
+   public String getUserName()
+   {
+      return userName;
+   }
+   
+   /**
+    * Set password, null by default.
+    */
+   public void setPassword(final String password)
+   {
+      this.password = password;
+   }
+   
+   /**
+    * Get password, may be null.
+    */
+   public String getPassword()
+   {
+      return password;
+   }
+   
+   /**
+    * Get client id, may be null.
+    */
+   public String getClientID()
+   {
+      return clientID;
+   }
+   
+   /**
+    * Set client id, null by default.
+    */
+   public void setClientID(final String clientID)
+   {
+      this.clientID = clientID;
+   }
+
+   /**
+    * Set providerJNDI, the JMS provider adapter to use.
+    *
+    * <p>Defaults to java:DefaultJMSProvider.
+    */
+   public void setProviderJNDI(final String providerJNDI)
+   {
+      this.providerJNDI  = providerJNDI;
+   }
+
+   /**
+    * Get providerJNDI. May not be null.
+    */
+   public String getProviderJNDI()
+   {
+      return providerJNDI;
+   }
+
+   /**
+    * Type of the JMS Session.
+    */
+   public int getType()
+   {
+      return type;
+   }
+
+   /**
+    * Set the default session type.
+    */
+   public void setType(int type)
+   {
+      this.type = type;
+   }
+
+   /**
+    * Helper method to set the default session type.
+    *
+    * @param type either javax.jms.Topic or javax.jms.Queue
+    * @exception ResourceException if type was not a valid type.
+    */
+   public void setSessionDefaultType(String type) throws ResourceException
+   {
+      if (type.equals(QUEUE_TYPE))
+         this.type = JmsConnectionFactory.QUEUE;
+      else if(type.equals(TOPIC_TYPE))
+         this.type = JmsConnectionFactory.TOPIC;
+      else
+         this.type = JmsConnectionFactory.BOTH;
+   }
+
+   public String getSessionDefaultType()
+   {
+      if (type == JmsConnectionFactory.BOTH)
+         return "both";
+      else if (type == JmsConnectionFactory.QUEUE)
+         return TOPIC_TYPE;
+      else
+         return QUEUE_TYPE;
+   }
+
+   /**
+    * Test for equality of all attributes.
+    */
+   public boolean equals(Object obj)
+   {
+      if (obj == null) return false;
+      
+      if (obj instanceof JmsMCFProperties)
+      {
+         JmsMCFProperties you = (JmsMCFProperties) obj;
+         return (Strings.compare(userName, you.getUserName()) &&
+                 Strings.compare(password, you.getPassword()) &&
+                 Strings.compare(providerJNDI, you.getProviderJNDI()) &&
+                 this.type == you.type);
+      }
+      
+      return false;
+   }
+ 
+   /**
+    * Simple hashCode of all attributes. 
+    */
+   public int hashCode()
+   {
+      // FIXME
+      String result = "" + userName + password + providerJNDI + type;
+      return result.hashCode();
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsManagedConnection.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsManagedConnection.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsManagedConnection.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,781 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.jms.Connection;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.QueueConnection;
+import javax.jms.QueueSession;
+import javax.jms.Session;
+import javax.jms.TopicConnection;
+import javax.jms.TopicSession;
+import javax.jms.XAConnection;
+import javax.jms.XAQueueConnection;
+import javax.jms.XAQueueSession;
+import javax.jms.XASession;
+import javax.jms.XATopicConnection;
+import javax.jms.XATopicSession;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.resource.NotSupportedException;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionEvent;
+import javax.resource.spi.ConnectionEventListener;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.IllegalStateException;
+import javax.resource.spi.LocalTransaction;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionMetaData;
+import javax.resource.spi.SecurityException;
+import javax.security.auth.Subject;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.jms.ConnectionFactoryHelper;
+import org.jboss.jms.jndi.JMSProviderAdapter;
+import org.jboss.logging.Logger;
+import org.jboss.resource.JBossResourceException;
+
+/**
+ * Managed Connection, manages one or more JMS sessions.
+ *
+ * <p>Every ManagedConnection will have a physical JMSConnection under the
+ *    hood. This may leave out several session, as specifyed in 5.5.4 Multiple
+ *    Connection Handles. Thread safe semantics is provided
+ *
+ * <p>Hm. If we are to follow the example in 6.11 this will not work. We would
+ *    have to use the SAME session. This means we will have to guard against
+ *    concurrent access. We use a stack, and only allowes the handle at the
+ *    top of the stack to do things.
+ *
+ * <p>As to transactions we some fairly hairy alternatives to handle:
+ *    XA - we get an XA. We may now only do transaction through the
+ *    XAResource, since a XASession MUST throw exceptions in commit etc. But
+ *    since XA support implies LocatTransaction support, we will have to use
+ *    the XAResource in the LocalTransaction class.
+ *    LocalTx - we get a normal session. The LocalTransaction will then work
+ *    against the normal session api.
+ *
+ * <p>An invokation of JMS MAY BE DONE in none transacted context. What do we
+ *    do then? How much should we leave to the user???
+ *
+ * <p>One possible solution is to use transactions any way, but under the hood.
+ *    If not LocalTransaction or XA has been aquired by the container, we have
+ *    to do the commit in send and publish. (CHECK is the container required
+ *    to get a XA every time it uses a managed connection? No its is not, only
+ *    at creation!)
+ *
+ * <p>Does this mean that a session one time may be used in a transacted env,
+ *    and another time in a not transacted.
+ *
+ * <p>Maybe we could have this simple rule:
+ *
+ * <p>If a user is going to use non trans:
+ * <ul>
+ * <li>mark that i ra deployment descr
+ * <li>Use a JmsProviderAdapter with non XA factorys
+ * <li>Mark session as non transacted (this defeats the purpose of specifying
+ * <li>trans attrinbutes in deploy descr NOT GOOD
+ * </ul>
+ *
+ * <p>From the JMS tutorial:
+ *    "When you create a session in an enterprise bean, the container ignores
+ *    the arguments you specify, because it manages all transactional
+ *    properties for enterprise beans."
+ *
+ * <p>And further:
+ *    "You do not specify a message acknowledgment mode when you create a
+ *    message-driven bean that uses container-managed transactions. The
+ *    container handles acknowledgment automatically."
+ *
+ * <p>On Session or Connection:
+ * <p>From Tutorial:
+ *    "A JMS API resource is a JMS API connection or a JMS API session." But in
+ *    the J2EE spec only connection is considered a resource.
+ *
+ * <p>Not resolved: connectionErrorOccurred: it is verry hard to know from the
+ *    exceptions thrown if it is a connection error. Should we register an
+ *    ExceptionListener and mark al handles as errounous? And then let them
+ *    send the event and throw an exception?
+ *
+ * @author <a href="mailto:peter.antman at tim.se">Peter Antman</a>.
+ * @author <a href="mailto:jason at planet57.com">Jason Dillon</a>
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsManagedConnection
+   implements ManagedConnection, ExceptionListener
+{
+   private static final Logger log = Logger.getLogger(JmsManagedConnection.class);
+
+   private JmsManagedConnectionFactory mcf;
+   private JmsConnectionRequestInfo info;
+   private String user;
+   private String pwd;
+   private boolean isDestroyed;
+
+   // Physical JMS connection stuff
+   private Connection con;
+   private Session session;
+   private TopicSession topicSession;
+   private QueueSession queueSession;
+   private XASession xaSession;
+   private XATopicSession xaTopicSession;
+   private XAQueueSession xaQueueSession;
+   private XAResource xaResource;
+   private boolean xaTransacted;
+
+   /** Holds all current JmsSession handles. */
+   private Set handles = Collections.synchronizedSet(new HashSet());
+
+   /** The event listeners */
+   private Vector listeners = new Vector();
+
+   /**
+    * Create a <tt>JmsManagedConnection</tt>.
+    *
+    * @param mcf
+    * @param info
+    * @param user
+    * @param pwd
+    *
+    * @throws ResourceException
+    */
+   public JmsManagedConnection(final JmsManagedConnectionFactory mcf,
+                               final ConnectionRequestInfo info,
+                               final String user,
+                               final String pwd)
+      throws ResourceException
+   {
+      this.mcf = mcf;
+
+      // seem like its asking for trouble here
+      this.info = (JmsConnectionRequestInfo)info;
+      this.user = user;
+      this.pwd = pwd;
+
+      setup();
+   }
+
+   //---- ManagedConnection API ----
+
+   /**
+    * Get the physical connection handler.
+    *
+    * <p>This bummer will be called in two situations:
+    * <ol>
+    * <li>When a new mc has bean created and a connection is needed
+    * <li>When an mc has been fetched from the pool (returned in match*)
+    * </ol>
+    *
+    * <p>It may also be called multiple time without a cleanup, to support
+    *    connection sharing.
+    *
+    * @param subject
+    * @param info
+    * @return           A new connection object.
+    *
+    * @throws ResourceException
+    */
+   public Object getConnection(final Subject subject,
+                               final ConnectionRequestInfo info)
+      throws ResourceException
+   {
+      // Check user first
+      JmsCred cred = JmsCred.getJmsCred(mcf,subject,info);
+
+      // Null users are allowed!
+      if (user != null && !user.equals(cred.name))
+         throw new SecurityException
+            ("Password credentials not the same, reauthentication not allowed");
+      if (cred.name != null && user == null) {
+         throw new SecurityException
+            ("Password credentials not the same, reauthentication not allowed");
+      }
+
+      user = cred.name; // Basically meaningless
+
+      if (isDestroyed)
+         throw new IllegalStateException("ManagedConnection already destroyd");
+
+      // Create a handle
+      JmsSession handle = new JmsSession(this, (JmsConnectionRequestInfo) info);
+      handles.add(handle);
+      return handle;
+   }
+
+   /**
+    * Destroy all handles.
+    *
+    * @throws ResourceException    Failed to close one or more handles.
+    */
+   private void destroyHandles() throws ResourceException
+   {
+      try
+      {
+         if (con != null)
+            con.stop();  
+      }
+      catch (Throwable t)
+      {
+         log.trace("Ignored error stopping connection", t);
+      }
+      
+      Iterator iter = handles.iterator();
+      while (iter.hasNext())
+         ((JmsSession)iter.next()).destroy();
+
+      // clear the handles map
+      handles.clear();
+   }
+
+   /**
+    * Destroy the physical connection.
+    *
+    * @throws ResourceException    Could not property close the session and
+    *                              connection.
+    */
+   public void destroy() throws ResourceException
+   {
+      if (isDestroyed) return;
+
+      isDestroyed = true;
+
+      try
+      {
+         con.setExceptionListener(null);
+      }
+      catch (JMSException e)
+      {
+         log.debug("Error unsetting the exception listener " + this, e);
+      }
+      
+      // destory handles
+      destroyHandles();
+      
+      try
+      {
+         // Close session and connection
+         try
+         {
+            if (info.getType() == JmsConnectionFactory.TOPIC)
+            {
+               topicSession.close();
+               if (xaTransacted) {
+                  xaTopicSession.close();
+               }
+            }
+            else if (info.getType() == JmsConnectionFactory.QUEUE)
+            {
+               queueSession.close();
+               if (xaTransacted)
+                  xaQueueSession.close();
+            }
+            else
+            {
+               session.close();
+               if (xaTransacted)
+                  xaSession.close();
+            }
+         }
+         catch (JMSException e)
+         {
+            log.debug("Error closing session " +this, e);
+         }
+         con.close();
+      }
+      catch (JMSException e)
+      {
+         throw new JBossResourceException
+            ("Could not properly close the session and connection", e);
+      }
+   }
+
+   /**
+    * Cleans up the, from the spec
+    *  - The cleanup of ManagedConnection instance resets its client specific
+    *    state.
+    *
+    * Does that mean that autentication should be redone. FIXME
+    */
+   public void cleanup() throws ResourceException
+   {
+      if (isDestroyed)
+         throw new IllegalStateException("ManagedConnection already destroyed");
+
+      // destory handles
+      destroyHandles();
+   }
+
+   /**
+    * Move a handler from one mc to this one.
+    *
+    * @param obj   An object of type JmsSession.
+    *
+    * @throws ResourceException        Failed to associate connection.
+    * @throws IllegalStateException    ManagedConnection in an illegal state.
+    */
+   public void associateConnection(final Object obj)
+      throws ResourceException
+   {
+      //
+      // Should we check auth, ie user and pwd? FIXME
+      //
+
+      if (!isDestroyed && obj instanceof JmsSession)
+      {
+         JmsSession h = (JmsSession)obj;
+         h.setManagedConnection(this);
+         handles.add(h);
+      }
+      else
+         throw new IllegalStateException
+            ("ManagedConnection in an illegal state");
+   }
+
+   /**
+    * Add a connection event listener.
+    *
+    * @param l   The connection event listener to be added.
+    */
+   public void addConnectionEventListener(final ConnectionEventListener l)
+   {
+      listeners.addElement(l);
+
+      if (log.isTraceEnabled())
+         log.trace("ConnectionEvent listener added: " + l);
+   }
+
+   /**
+    * Remove a connection event listener.
+    *
+    * @param l    The connection event listener to be removed.
+    */
+   public void removeConnectionEventListener(final ConnectionEventListener l)
+   {
+      listeners.removeElement(l);
+   }
+
+   /**
+    * Get the XAResource for the connection.
+    *
+    * @return   The XAResource for the connection.
+    *
+    * @throws ResourceException    XA transaction not supported
+    */
+   public XAResource getXAResource() throws ResourceException
+   {
+      //
+      // Spec says a mc must allways return the same XA resource,
+      // so we cache it.
+      //
+      if (!xaTransacted)
+         throw new NotSupportedException("Non XA transaction not supported");
+
+      if (xaResource == null)
+      {
+         if (info.getType() == JmsConnectionFactory.TOPIC)
+            xaResource = xaTopicSession.getXAResource();
+         else if (info.getType() == JmsConnectionFactory.QUEUE)
+            xaResource = xaQueueSession.getXAResource();
+         else
+            xaResource = xaSession.getXAResource();
+      }
+
+      if (log.isTraceEnabled())
+         log.trace("XAResource=" + xaResource);
+
+      return xaResource;
+   }
+
+   /**
+    * Get the location transaction for the connection.
+    *
+    * @return    The local transaction for the connection.
+    *
+    * @throws ResourceException
+    */
+   public LocalTransaction getLocalTransaction() throws ResourceException
+   {
+      LocalTransaction tx = new JmsLocalTransaction(this);
+      if (log.isTraceEnabled())
+         log.trace("LocalTransaction=" + tx);
+      return tx;
+   }
+
+   /**
+    * Get the meta data for the connection.
+    *
+    * @return    The meta data for the connection.
+    *
+    * @throws ResourceException
+    * @throws IllegalStateException    ManagedConnection already destroyed.
+    */
+   public ManagedConnectionMetaData getMetaData() throws ResourceException
+   {
+      if (isDestroyed)
+         throw new IllegalStateException("ManagedConnection already destroyd");
+
+      return new JmsMetaData(this);
+   }
+
+   /**
+    * Set the log writer for this connection.
+    *
+    * @param out   The log writer for this connection.
+    *
+    * @throws ResourceException
+    */
+   public void setLogWriter(final PrintWriter out) throws ResourceException
+   {
+      //
+      // jason: screw the logWriter stuff for now it sucks ass
+      //
+   }
+
+   /**
+    * Get the log writer for this connection.
+    *
+    * @return   Always null
+    */
+   public PrintWriter getLogWriter() throws ResourceException
+   {
+      //
+      // jason: screw the logWriter stuff for now it sucks ass
+      //
+
+      return null;
+   }
+
+   // --- Exception listener implementation
+   
+   public void onException(JMSException exception)
+   {
+      if (isDestroyed)
+      {
+         if (log.isTraceEnabled())
+            log.trace("Ignoring error on already destroyed connection " + this, exception);
+         return;
+      }
+
+      log.warn("Handling jms exception failure: " + this, exception);
+
+      try
+      {
+         con.setExceptionListener(null);
+      }
+      catch (JMSException e)
+      {
+         log.debug("Unable to unset exception listener", e);
+      }
+      
+      ConnectionEvent event = new ConnectionEvent(this, ConnectionEvent.CONNECTION_ERROR_OCCURRED, exception);
+      sendEvent(event);
+   }
+   
+   // --- Api to JmsSession
+
+   /**
+    * Get the session for this connection.
+    *
+    * @return   Either a topic or queue connection.
+    */
+   protected Session getSession()
+   {
+      if (info.getType() == JmsConnectionFactory.TOPIC)
+         return topicSession;
+      else if (info.getType() == JmsConnectionFactory.QUEUE)
+         return queueSession;
+      else
+         return session;
+   }
+
+   /**
+    * Send an event.
+    *
+    * @param event    The event to send.
+    */
+   protected void sendEvent(final ConnectionEvent event)
+   {
+      int type = event.getId();
+
+      if (log.isTraceEnabled())
+         log.trace("Sending connection event: " + type);
+
+      // convert to an array to avoid concurrent modification exceptions
+      ConnectionEventListener[] list =
+         (ConnectionEventListener[])listeners.toArray(new ConnectionEventListener[listeners.size()]);
+
+      for (int i=0; i<list.length; i++)
+      {
+         switch (type) {
+            case ConnectionEvent.CONNECTION_CLOSED:
+               list[i].connectionClosed(event);
+               break;
+
+            case ConnectionEvent.LOCAL_TRANSACTION_STARTED:
+               list[i].localTransactionStarted(event);
+               break;
+
+            case ConnectionEvent.LOCAL_TRANSACTION_COMMITTED:
+               list[i].localTransactionCommitted(event);
+               break;
+
+            case ConnectionEvent.LOCAL_TRANSACTION_ROLLEDBACK:
+               list[i].localTransactionRolledback(event);
+               break;
+
+            case ConnectionEvent.CONNECTION_ERROR_OCCURRED:
+               list[i].connectionErrorOccurred(event);
+               break;
+
+            default:
+               throw new IllegalArgumentException("Illegal eventType: " + type);
+         }
+      }
+   }
+
+   /**
+    * Remove a handle from the handle map.
+    *
+    * @param handle     The handle to remove.
+    */
+   protected void removeHandle(final JmsSession handle)
+   {
+      handles.remove(handle);
+   }
+
+   // --- Used by MCF
+
+   /**
+    * Get the request info for this connection.
+    *
+    * @return    The request info for this connection.
+    */
+   protected ConnectionRequestInfo getInfo()
+   {
+      return info;
+   }
+
+   /**
+    * Get the connection factory for this connection.
+    *
+    * @return    The connection factory for this connection.
+    */
+   protected JmsManagedConnectionFactory getManagedConnectionFactory()
+   {
+      return mcf;
+   }
+
+   void start() throws JMSException
+   {
+      con.start();
+   }
+
+   void stop() throws JMSException
+   {
+      con.stop();
+   }
+   
+   // --- Used by MetaData
+
+   /**
+    * Get the user name for this connection.
+    *
+    * @return    The user name for this connection.
+    */
+   protected String getUserName()
+   {
+      return user;
+   }
+
+   // --- Private helper methods
+
+   /**
+    * Get the JMS provider adapter that will be used to create JMS
+    * resources.
+    *
+    * @return    A JMS provider adapter.
+    *
+    * @throws NamingException    Failed to lookup provider adapter.
+    */
+   private JMSProviderAdapter getProviderAdapter() throws NamingException
+   {
+      JMSProviderAdapter adapter;
+
+      if (mcf.getJmsProviderAdapterJNDI() != null)
+      {
+         // lookup the adapter from JNDI
+         Context ctx = new InitialContext();
+         try
+         {
+            adapter = (JMSProviderAdapter)
+               ctx.lookup(mcf.getJmsProviderAdapterJNDI());
+         }
+         finally
+         {
+            ctx.close();
+         }
+      }
+      else
+         adapter = mcf.getJmsProviderAdapter();
+
+      return adapter;
+   }
+
+   /**
+    * Setup the connection.
+    *
+    * @throws ResourceException
+    */
+   private void setup() throws ResourceException
+   {
+      boolean trace = log.isTraceEnabled();
+
+      try
+      {
+         JMSProviderAdapter adapter = getProviderAdapter();
+         Context context = adapter.getInitialContext();
+         Object factory;
+         boolean transacted = info.isTransacted();
+         int ack = Session.AUTO_ACKNOWLEDGE;
+
+         if (info.getType() == JmsConnectionFactory.TOPIC)
+         {
+            String jndi = adapter.getTopicFactoryRef();
+            if (jndi == null)
+               throw new IllegalStateException("No configured 'TopicFactoryRef' on the jms provider " + mcf.getJmsProviderAdapterJNDI());
+            factory = context.lookup(jndi);
+            con = ConnectionFactoryHelper.createTopicConnection(factory, user, pwd);
+            if (info.getClientID() != null)
+               con.setClientID(info.getClientID());
+            con.setExceptionListener(this);
+            if (trace)
+               log.trace("created connection: " + con);
+
+            if (con instanceof XATopicConnection)
+            {
+               xaTopicSession = ((XATopicConnection)con).createXATopicSession();
+               topicSession = xaTopicSession.getTopicSession();
+               xaTransacted = true;
+            }
+            else if (con instanceof TopicConnection)
+            {
+               topicSession =
+                  ((TopicConnection)con).createTopicSession(transacted, ack);
+               if (trace)
+                  log.trace("Using a non-XA TopicConnection.  " +
+                            "It will not be able to participate in a Global UOW");
+            }
+            else
+               throw new JBossResourceException("Connection was not recognizable: " + con);
+
+            if (trace)
+               log.trace("xaTopicSession=" + xaTopicSession + ", topicSession=" + topicSession);
+         }
+         else if (info.getType() == JmsConnectionFactory.QUEUE)
+         {
+            String jndi = adapter.getQueueFactoryRef();
+            if (jndi == null)
+               throw new IllegalStateException("No configured 'QueueFactoryRef' on the jms provider " + mcf.getJmsProviderAdapterJNDI());
+            factory = context.lookup(jndi);
+            con = ConnectionFactoryHelper.createQueueConnection(factory, user, pwd);
+            if (info.getClientID() != null)
+               con.setClientID(info.getClientID());
+            con.setExceptionListener(this);
+            if (trace) 
+               log.debug("created connection: " + con);
+
+            if (con instanceof XAQueueConnection)
+            {
+               xaQueueSession =
+                  ((XAQueueConnection)con).createXAQueueSession();
+               queueSession = xaQueueSession.getQueueSession();
+               xaTransacted = true;
+            }
+            else if (con instanceof QueueConnection)
+            {
+               queueSession =
+                  ((QueueConnection)con).createQueueSession(transacted, ack);
+               if (trace)
+                  log.trace("Using a non-XA QueueConnection.  " +
+                            "It will not be able to participate in a Global UOW");
+            }
+            else
+               throw new JBossResourceException("Connection was not reconizable: " + con);
+
+            if (trace)
+               log.trace("xaQueueSession=" + xaQueueSession + ", queueSession=" + queueSession);
+         }
+         else
+         {
+            String jndi = adapter.getFactoryRef();
+            if (jndi == null)
+               throw new IllegalStateException("No configured 'FactoryRef' on the jms provider " + mcf.getJmsProviderAdapterJNDI());
+            factory = context.lookup(jndi);
+            con = ConnectionFactoryHelper.createConnection(factory, user, pwd);
+            if (info.getClientID() != null)
+               con.setClientID(info.getClientID());
+            con.setExceptionListener(this);
+            if (trace) 
+               log.trace("created connection: " + con);
+
+            if (con instanceof XAConnection)
+            {
+               xaSession =
+                  ((XAConnection)con).createXASession();
+               session = xaSession.getSession();
+               xaTransacted = true;
+            }
+            else
+            {
+               session = con.createSession(transacted, ack);
+               if (trace)
+                  log.trace("Using a non-XA Connection.  " +
+                            "It will not be able to participate in a Global UOW");
+            }
+
+            if (trace)
+               log.debug("xaSession=" + xaQueueSession + ", Session=" + session);
+         }
+
+         if (trace)
+            log.debug("transacted=" + transacted + ", ack=" + ack);
+      }
+      catch (NamingException e)
+      {
+         throw new JBossResourceException("Unable to setup connection", e);
+      }
+      catch (JMSException e)
+      {
+         throw new JBossResourceException("Unable to setup connection", e);
+      }
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsManagedConnectionFactory.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsManagedConnectionFactory.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsManagedConnectionFactory.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,343 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.jms.ConnectionMetaData;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.security.auth.Subject;
+
+import org.jboss.jms.jndi.JMSProviderAdapter;
+import org.jboss.logging.Logger;
+
+/**
+ * Jms ManagedConectionFactory
+ * 
+ * @author <a href="mailto:peter.antman at tim.se">Peter Antman </a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsManagedConnectionFactory implements ManagedConnectionFactory
+{
+   private static final long serialVersionUID = -923483284031773011L;
+
+   private static final Logger log = Logger.getLogger(JmsManagedConnection.class);
+
+   /** Settable attributes in ra.xml */
+   private JmsMCFProperties mcfProperties = new JmsMCFProperties();
+
+   /** Whether we are strict */
+   private boolean strict = true;
+
+   /** For local access. */
+   private JMSProviderAdapter adapter;
+
+   public JmsManagedConnectionFactory()
+   {
+      // empty
+   }
+
+   /**
+    * Create a "non managed" connection factory. No appserver involved
+    */
+   public Object createConnectionFactory() throws ResourceException
+   {
+      return createConnectionFactory(null);
+   }
+
+   /**
+    * Create a ConnectionFactory with appserver hook
+    */
+   public Object createConnectionFactory(ConnectionManager cxManager) throws ResourceException
+   {
+      Object cf = new JmsConnectionFactoryImpl(this, cxManager);
+
+      if (log.isTraceEnabled())
+      {
+         log.trace("Created connection factory: " + cf + ", using connection manager: " + cxManager);
+      }
+
+      return cf;
+   }
+
+   /**
+    * Create a new connection to manage in pool
+    */
+   public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo info)
+         throws ResourceException
+   {
+      boolean trace = log.isTraceEnabled();
+
+      info = getInfo(info);
+      if (trace)
+         log.trace("connection request info: " + info);
+
+      JmsCred cred = JmsCred.getJmsCred(this, subject, info);
+      if (trace)
+         log.trace("jms credentials: " + cred);
+
+      // OK we got autentication stuff
+      JmsManagedConnection mc = new JmsManagedConnection(this, info, cred.name, cred.pwd);
+
+      if (trace)
+         log.trace("created new managed connection: " + mc);
+
+      return mc;
+   }
+
+   /**
+    * Match a set of connections from the pool
+    */
+   public ManagedConnection matchManagedConnections(Set connectionSet, Subject subject, ConnectionRequestInfo info)
+         throws ResourceException
+   {
+      boolean trace = log.isTraceEnabled();
+
+      // Get cred
+      info = getInfo(info);
+      JmsCred cred = JmsCred.getJmsCred(this, subject, info);
+
+      if (trace)
+         log.trace("Looking for connection matching credentials: " + cred);
+
+      // Traverse the pooled connections and look for a match, return first
+      // found
+      Iterator connections = connectionSet.iterator();
+
+      while (connections.hasNext())
+      {
+         Object obj = connections.next();
+
+         // We only care for connections of our own type
+         if (obj instanceof JmsManagedConnection)
+         {
+            // This is one from the pool
+            JmsManagedConnection mc = (JmsManagedConnection) obj;
+
+            // Check if we even created this on
+            ManagedConnectionFactory mcf = mc.getManagedConnectionFactory();
+
+            // Only admit a connection if it has the same username as our
+            // asked for creds
+
+            // FIXME, Here we have a problem, jms connection
+            // may be anonymous, have a user name
+
+            if ((mc.getUserName() == null || (mc.getUserName() != null && mc.getUserName().equals(cred.name)))
+                  && mcf.equals(this))
+            {
+               // Now check if ConnectionInfo equals
+               if (info.equals(mc.getInfo()))
+               {
+
+                  if (trace)
+                     log.trace("Found matching connection: " + mc);
+
+                  return mc;
+               }
+            }
+         }
+      }
+
+      if (trace)
+         log.trace("No matching connection was found");
+
+      return null;
+   }
+
+   public void setLogWriter(PrintWriter out) throws ResourceException
+   {
+      // 
+      // jason: screw the logWriter stuff for now it sucks ass
+      //
+   }
+
+   public PrintWriter getLogWriter() throws ResourceException
+   {
+      // 
+      // jason: screw the logWriter stuff for now it sucks ass
+      //
+
+      return null;
+   }
+
+   /**
+    * Checks for equality ower the configured properties.
+    */
+   public boolean equals(Object obj)
+   {
+      if (obj == null)
+         return false;
+      if (obj instanceof JmsManagedConnectionFactory)
+      {
+         return mcfProperties.equals(((JmsManagedConnectionFactory) obj).getProperties());
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   public int hashCode()
+   {
+      return mcfProperties.hashCode();
+   }
+
+   // --- Connfiguration API ---
+
+   public void setJmsProviderAdapterJNDI(String jndi)
+   {
+      mcfProperties.setProviderJNDI(jndi);
+   }
+
+   public String getJmsProviderAdapterJNDI()
+   {
+      return mcfProperties.getProviderJNDI();
+   }
+
+   /**
+    * Set userName, null by default.
+    */
+   public void setUserName(String userName)
+   {
+      mcfProperties.setUserName(userName);
+   }
+
+   /**
+    * Get userName, may be null.
+    */
+   public String getUserName()
+   {
+      return mcfProperties.getUserName();
+   }
+
+   /**
+    * Set password, null by default.
+    */
+   public void setPassword(String password)
+   {
+      mcfProperties.setPassword(password);
+   }
+
+   /**
+    * Get password, may be null.
+    */
+   public String getPassword()
+   {
+      return mcfProperties.getPassword();
+   }
+
+   /**
+    * Get client id, may be null.
+    */
+   public String getClientID()
+   {
+      return mcfProperties.getClientID();
+   }
+
+   /**
+    * Set client id, null by default.
+    */
+   public void setClientID(final String clientID)
+   {
+      mcfProperties.setClientID(clientID);
+   }
+
+   public boolean isStrict()
+   {
+      return strict;
+   }
+
+   public void setStrict(boolean strict)
+   {
+      this.strict = strict;
+   }
+
+   public void setStrict(Boolean strict)
+   {
+      this.strict = strict.booleanValue();
+   }
+
+   /**
+    * Set the default session typ
+    * 
+    * @param type either javax.jms.Topic or javax.jms.Queue
+    * 
+    * @exception ResourceException if type was not a valid type.
+    */
+   public void setSessionDefaultType(String type) throws ResourceException
+   {
+      mcfProperties.setSessionDefaultType(type);
+   }
+
+   public String getSessionDefaultType()
+   {
+      return mcfProperties.getSessionDefaultType();
+   }
+
+   /**
+    * For local access
+    */
+   public void setJmsProviderAdapter(final JMSProviderAdapter adapter)
+   {
+      this.adapter = adapter;
+   }
+
+   public JMSProviderAdapter getJmsProviderAdapter()
+   {
+      return adapter;
+   }
+
+   private ConnectionRequestInfo getInfo(ConnectionRequestInfo info)
+   {
+      if (info == null)
+      {
+         // Create a default one
+         return new JmsConnectionRequestInfo(mcfProperties);
+      }
+      else
+      {
+         // Fill the one with any defaults
+         ((JmsConnectionRequestInfo) info).setDefaults(mcfProperties);
+         return info;
+      }
+   }
+
+   public ConnectionMetaData getMetaData()
+   {
+      return new JmsConnectionMetaData();
+   }
+
+   //---- MCF to MCF API
+
+   protected JmsMCFProperties getProperties()
+   {
+      return mcfProperties;
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMapMessage.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMapMessage.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMapMessage.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,172 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.util.Enumeration;
+
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+
+/**
+ * A wrapper for a message
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsMapMessage extends JmsMessage implements MapMessage
+{
+   /**
+    * Create a new wrapper
+    * 
+    * @param message the message
+    * @param session the session
+    */
+   public JmsMapMessage(MapMessage message, JmsSession session)
+   {
+      super(message, session);
+   }
+
+   public boolean getBoolean(String name) throws JMSException
+   {
+      return ((MapMessage) message).getBoolean(name);
+   }
+   
+   public byte getByte(String name) throws JMSException
+   {
+      return ((MapMessage) message).getByte(name);
+   }
+
+   public byte[] getBytes(String name) throws JMSException
+   {
+      return ((MapMessage) message).getBytes(name);
+   }
+
+   public char getChar(String name) throws JMSException
+   {
+      return ((MapMessage) message).getChar(name);
+   }
+
+   public double getDouble(String name) throws JMSException
+   {
+      return ((MapMessage) message).getDouble(name);
+   }
+
+   public float getFloat(String name) throws JMSException
+   {
+      return ((MapMessage) message).getFloat(name);
+   }
+   
+   public int getInt(String name) throws JMSException
+   {
+      return ((MapMessage) message).getInt(name);
+   }
+
+   public long getLong(String name) throws JMSException
+   {
+      return ((MapMessage) message).getLong(name);
+   }
+
+   public Enumeration getMapNames() throws JMSException
+   {
+      return ((MapMessage) message).getMapNames();
+   }
+
+   public Object getObject(String name) throws JMSException
+   {
+      return ((MapMessage) message).getObject(name);
+   }
+
+   public short getShort(String name) throws JMSException
+   {
+      return ((MapMessage) message).getShort(name);
+   }
+
+   public String getString(String name) throws JMSException
+   {
+      return ((MapMessage) message).getString(name);
+   }
+
+   public boolean itemExists(String name) throws JMSException
+   {
+      return ((MapMessage) message).itemExists(name);
+   }
+
+   public void setBoolean(String name, boolean value) throws JMSException
+   {
+      ((MapMessage) message).setBoolean(name, value);
+   }
+
+   public void setByte(String name, byte value) throws JMSException
+   {
+      ((MapMessage) message).setByte(name, value);
+   }
+
+   public void setBytes(String name, byte[] value, int offset, int length) throws JMSException
+   {
+      ((MapMessage) message).setBytes(name, value, offset, length);
+   }
+
+   public void setBytes(String name, byte[] value) throws JMSException
+   {
+      ((MapMessage) message).setBytes(name, value);
+   }
+
+   public void setChar(String name, char value) throws JMSException
+   {
+      ((MapMessage) message).setChar(name, value);
+   }
+
+   public void setDouble(String name, double value) throws JMSException
+   {
+      ((MapMessage) message).setDouble(name, value);
+   }
+
+   public void setFloat(String name, float value) throws JMSException
+   {
+      ((MapMessage) message).setFloat(name, value);
+   }
+
+   public void setInt(String name, int value) throws JMSException
+   {
+      ((MapMessage) message).setInt(name, value);
+   }
+
+   public void setLong(String name, long value) throws JMSException
+   {
+      ((MapMessage) message).setLong(name, value);
+   }
+   
+   public void setObject(String name, Object value) throws JMSException
+   {
+      ((MapMessage) message).setObject(name, value);
+   }
+   
+   public void setShort(String name, short value) throws JMSException
+   {
+      ((MapMessage) message).setShort(name, value);
+   }
+
+   public void setString(String name, String value) throws JMSException
+   {
+      ((MapMessage) message).setString(name, value);
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessage.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessage.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessage.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,299 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.util.Enumeration;
+
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+
+/**
+ * A wrapper for a message
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsMessage implements Message
+{
+   /** The message */
+   Message message;
+   
+   /** The session */
+   JmsSession session;
+
+   /**
+    * Create a new wrapper
+    * 
+    * @param message the message
+    * @param session the session
+    */
+   public JmsMessage(Message message, JmsSession session)
+   {
+      this.message = message;
+      this.session = session;
+   }
+
+   public void acknowledge() throws JMSException
+   {
+      session.getSession(); // Check for closed
+      message.acknowledge();
+   }
+   
+   public void clearBody() throws JMSException
+   {
+      message.clearBody();
+   }
+   
+   public void clearProperties() throws JMSException
+   {
+      message.clearProperties();
+   }
+   
+   public boolean getBooleanProperty(String name) throws JMSException
+   {
+      return message.getBooleanProperty(name);
+   }
+   
+   public byte getByteProperty(String name) throws JMSException
+   {
+      return message.getByteProperty(name);
+   }
+
+   public double getDoubleProperty(String name) throws JMSException
+   {
+      return message.getDoubleProperty(name);
+   }
+   
+   public float getFloatProperty(String name) throws JMSException
+   {
+      return message.getFloatProperty(name);
+   }
+   
+   public int getIntProperty(String name) throws JMSException
+   {
+      return message.getIntProperty(name);
+   }
+   
+   public String getJMSCorrelationID() throws JMSException
+   {
+      return message.getJMSCorrelationID();
+   }
+   
+   public byte[] getJMSCorrelationIDAsBytes() throws JMSException
+   {
+      return message.getJMSCorrelationIDAsBytes();
+   }
+   
+   public int getJMSDeliveryMode() throws JMSException
+   {
+      return message.getJMSDeliveryMode();
+   }
+   
+   public Destination getJMSDestination() throws JMSException
+   {
+      return message.getJMSDestination();
+   }
+   
+   public long getJMSExpiration() throws JMSException
+   {
+      return message.getJMSExpiration();
+   }
+   
+   public String getJMSMessageID() throws JMSException
+   {
+      return message.getJMSMessageID();
+   }
+   
+   public int getJMSPriority() throws JMSException
+   {
+      return message.getJMSPriority();
+   }
+   
+   public boolean getJMSRedelivered() throws JMSException
+   {
+      return message.getJMSRedelivered();
+   }
+   
+   public Destination getJMSReplyTo() throws JMSException
+   {
+      return message.getJMSReplyTo();
+   }
+   
+   public long getJMSTimestamp() throws JMSException
+   {
+      return message.getJMSTimestamp();
+   }
+   
+   public String getJMSType() throws JMSException
+   {
+      return message.getJMSType();
+   }
+   
+   public long getLongProperty(String name) throws JMSException
+   {
+      return message.getLongProperty(name);
+   }
+   
+   public Object getObjectProperty(String name) throws JMSException
+   {
+      return message.getObjectProperty(name);
+   }
+   
+   public Enumeration getPropertyNames() throws JMSException
+   {
+      return message.getPropertyNames();
+   }
+   
+   public short getShortProperty(String name) throws JMSException
+   {
+      return message.getShortProperty(name);
+   }
+   
+   public String getStringProperty(String name) throws JMSException
+   {
+      return message.getStringProperty(name);
+   }
+   
+   public boolean propertyExists(String name) throws JMSException
+   {
+      return message.propertyExists(name);
+   }
+   
+   public void setBooleanProperty(String name, boolean value) throws JMSException
+   {
+      message.setBooleanProperty(name, value);
+   }
+   
+   public void setByteProperty(String name, byte value) throws JMSException
+   {
+      message.setByteProperty(name, value);
+   }
+   
+   public void setDoubleProperty(String name, double value) throws JMSException
+   {
+      message.setDoubleProperty(name, value);
+   }
+   
+   public void setFloatProperty(String name, float value) throws JMSException
+   {
+      message.setFloatProperty(name, value);
+   }
+   
+   public void setIntProperty(String name, int value) throws JMSException
+   {
+      message.setIntProperty(name, value);
+   }
+   
+   public void setJMSCorrelationID(String correlationID) throws JMSException
+   {
+      message.setJMSCorrelationID(correlationID);
+   }
+
+   public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException
+   {
+      message.setJMSCorrelationIDAsBytes(correlationID);
+   }
+
+   public void setJMSDeliveryMode(int deliveryMode) throws JMSException
+   {
+      message.setJMSDeliveryMode(deliveryMode);
+   }
+
+   public void setJMSDestination(Destination destination) throws JMSException
+   {
+      message.setJMSDestination(destination);
+   }
+   
+   public void setJMSExpiration(long expiration) throws JMSException
+   {
+      message.setJMSExpiration(expiration);
+   }
+   
+   public void setJMSMessageID(String id) throws JMSException
+   {
+      message.setJMSMessageID(id);
+   }
+   
+   public void setJMSPriority(int priority) throws JMSException
+   {
+      message.setJMSPriority(priority);
+   }
+   
+   public void setJMSRedelivered(boolean redelivered) throws JMSException
+   {
+      message.setJMSRedelivered(redelivered);
+   }
+
+   public void setJMSReplyTo(Destination replyTo) throws JMSException
+   {
+      message.setJMSReplyTo(replyTo);
+   }
+
+   public void setJMSTimestamp(long timestamp) throws JMSException
+   {
+      message.setJMSTimestamp(timestamp);
+   }
+   
+   public void setJMSType(String type) throws JMSException
+   {
+      message.setJMSType(type);
+   }
+   
+   public void setLongProperty(String name, long value) throws JMSException
+   {
+      message.setLongProperty(name, value);
+   }
+   
+   public void setObjectProperty(String name, Object value) throws JMSException
+   {
+      message.setObjectProperty(name, value);
+   }
+   
+   public void setShortProperty(String name, short value) throws JMSException
+   {
+      message.setShortProperty(name, value);
+   }
+   
+   public void setStringProperty(String name, String value) throws JMSException
+   {
+      message.setStringProperty(name, value);
+   }
+   
+   public int hashCode()
+   {
+      return message.hashCode();
+   }
+   
+   public boolean equals(Object object)
+   {
+      if (object != null && object instanceof JmsMessage)
+         return message.equals(((JmsMessage) object).message);
+      else
+         return message.equals(object);
+   }
+   
+   public String toString()
+   {
+      return message.toString();
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessageConsumer.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessageConsumer.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessageConsumer.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,167 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.ObjectMessage;
+import javax.jms.StreamMessage;
+import javax.jms.TextMessage;
+
+import org.jboss.logging.Logger;
+
+/**
+ * A wrapper for a message consumer
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsMessageConsumer implements MessageConsumer
+{
+   private static final Logger log = Logger.getLogger(JmsMessageConsumer.class);
+
+   /** The wrapped message consumer */
+   MessageConsumer consumer;
+   
+   /** The session for this consumer */
+   JmsSession session;
+   
+   /** Whether trace is enabled */
+   private boolean trace = log.isTraceEnabled();
+
+   /**
+    * Create a new wrapper
+    * 
+    * @param consumer the consumer
+    * @param session the session
+    */
+   public JmsMessageConsumer(MessageConsumer consumer, JmsSession session)
+   {
+      this.consumer = consumer;
+      this.session = session;
+      
+      if (trace)
+         log.trace("new JmsMessageConsumer " + this + " consumer=" + consumer + " session=" + session);
+   }
+
+   public void close() throws JMSException
+   {
+      if (trace)
+         log.trace("close " + this);
+      try
+      {
+         closeConsumer();
+      }
+      finally
+      {
+         session.removeConsumer(this);
+      }
+   }
+   
+   public MessageListener getMessageListener() throws JMSException
+   {
+      session.checkStrict();
+      return consumer.getMessageListener();
+   }
+   
+   public String getMessageSelector() throws JMSException
+   {
+      return consumer.getMessageSelector();
+   }
+   
+   public Message receive() throws JMSException
+   {
+      if (trace)
+         log.trace("receive " + this);
+      Message message = consumer.receive();
+      if (trace)
+         log.trace("received " + this + " result=" + message);
+      if (message == null)
+         return null;
+      else
+         return wrapMessage(message);
+   }
+
+   public Message receive(long timeout) throws JMSException
+   {
+      if (trace)
+         log.trace("receive " + this + " timeout=" + timeout);
+      Message message = consumer.receive(timeout);
+      if (trace)
+         log.trace("received " + this + " result=" + message);
+      if (message == null)
+         return null;
+      else
+         return wrapMessage(message);
+   }
+
+   public Message receiveNoWait() throws JMSException
+   {
+      if (trace)
+         log.trace("receiveNoWait " + this);
+      Message message = consumer.receiveNoWait();
+      if (trace)
+         log.trace("received " + this + " result=" + message);
+      if (message == null)
+         return null;
+      else
+         return wrapMessage(message);
+   }
+   
+   public void setMessageListener(MessageListener listener) throws JMSException
+   {
+      session.checkStrict();
+      if (listener == null)
+         consumer.setMessageListener(null);
+      else
+         consumer.setMessageListener(wrapMessageListener(listener));
+   }
+
+   void closeConsumer() throws JMSException
+   {
+      consumer.close();
+   }
+   
+   Message wrapMessage(Message message)
+   {
+      if (message instanceof BytesMessage)
+         return new JmsBytesMessage((BytesMessage) message, session);
+      else if (message instanceof MapMessage)
+         return new JmsMapMessage((MapMessage) message, session);
+      else if (message instanceof ObjectMessage)
+         return new JmsObjectMessage((ObjectMessage) message, session);
+      else if (message instanceof StreamMessage)
+         return new JmsStreamMessage((StreamMessage) message, session);
+      else if (message instanceof TextMessage)
+         return new JmsTextMessage((TextMessage) message, session);
+      return new JmsMessage(message, session);
+   }
+   
+   MessageListener wrapMessageListener(MessageListener listener)
+   {
+      return new JmsMessageListener(listener, this);
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessageListener.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessageListener.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMessageListener.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.Message;
+import javax.jms.MessageListener;
+
+/**
+ * A wrapper for a message listener
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsMessageListener implements MessageListener
+{
+   /** The message listener */
+   MessageListener listener;
+   
+   /** The consumer */
+   JmsMessageConsumer consumer;
+
+   /**
+    * Create a new wrapper
+    * 
+    * @param listener the listener
+    * @param consumer the consumer
+    */
+   public JmsMessageListener(MessageListener listener, JmsMessageConsumer consumer)
+   {
+      this.listener = listener;
+      this.consumer = consumer;
+   }
+
+   public void onMessage(Message message)
+   {
+      message = consumer.wrapMessage(message);
+      listener.onMessage(message);
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMetaData.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMetaData.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsMetaData.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnectionMetaData;
+
+/**
+ * Jms Metadata
+ *
+ * @author <a href="mailto:peter.antman at tim.se">Peter Antman</a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsMetaData
+   implements ManagedConnectionMetaData
+{
+   private JmsManagedConnection mc;
+   
+   public JmsMetaData(final JmsManagedConnection mc) {
+      this.mc = mc;
+   }
+   
+   public String getEISProductName() throws ResourceException {
+      return "JMS CA Resource Adapter";
+   }
+
+   public String getEISProductVersion() throws ResourceException {
+      return "0.1";//Is this possible to get another way
+   }
+
+   public int getMaxConnections() throws ResourceException {
+      // Dont know how to get this, from Jms, we
+      // set it to unlimited
+      return 0;
+   }
+    
+   public String getUserName() throws ResourceException {
+      return mc.getUserName();
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsObjectMessage.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsObjectMessage.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsObjectMessage.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.io.Serializable;
+
+import javax.jms.JMSException;
+import javax.jms.ObjectMessage;
+
+/**
+ * A wrapper for a message
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsObjectMessage extends JmsMessage implements ObjectMessage
+{
+   /**
+    * Create a new wrapper
+    * 
+    * @param message the message
+    * @param session the session
+    */
+   public JmsObjectMessage(ObjectMessage message, JmsSession session)
+   {
+      super(message, session);
+   }
+
+   public Serializable getObject() throws JMSException
+   {
+      return ((ObjectMessage) message).getObject();
+   }
+   
+   public void setObject(Serializable object) throws JMSException
+   {
+      ((ObjectMessage) message).setObject(object);
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsQueueReceiver.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsQueueReceiver.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsQueueReceiver.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.JMSException;
+import javax.jms.Queue;
+import javax.jms.QueueReceiver;
+
+/**
+ * A wrapper for a queue receiver
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsQueueReceiver extends JmsMessageConsumer implements QueueReceiver
+{
+   /**
+    * Create a new wrapper
+    * 
+    * @param consumer the queue receiver
+    * @param session the session
+    */
+   public JmsQueueReceiver(QueueReceiver consumer, JmsSession session)
+   {
+      super(consumer, session);
+   }
+
+   public Queue getQueue() throws JMSException
+   {
+      return ((QueueReceiver) consumer).getQueue();
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsResourceAdapter.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsResourceAdapter.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsResourceAdapter.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,112 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.BootstrapContext;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterInternalException;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.resource.spi.work.WorkManager;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.logging.Logger;
+import org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.JmsActivation;
+import org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.JmsActivationSpec;
+
+import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
+
+/**
+ * A generic resource adapter for any JMS server.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsResourceAdapter implements ResourceAdapter
+{
+   /** The logger */
+   private static final Logger log = Logger.getLogger(JmsResourceAdapter.class);
+
+   /** The bootstrap context */
+   private BootstrapContext ctx;
+
+   /** The activations by activation spec */
+   private ConcurrentReaderHashMap activations = new ConcurrentReaderHashMap();
+   
+   /**
+    * Get the work manager
+    * 
+    * @return the work manager
+    */
+   public WorkManager getWorkManager()
+   {
+      return ctx.getWorkManager();
+   }
+
+   public void endpointActivation(MessageEndpointFactory endpointFactory, ActivationSpec spec) throws ResourceException
+   {
+      JmsActivation activation = new JmsActivation(this, endpointFactory, (JmsActivationSpec) spec);
+      activations.put(spec, activation);
+      activation.start();
+   }
+
+   public void endpointDeactivation(MessageEndpointFactory endpointFactory, ActivationSpec spec)
+   {
+      JmsActivation activation = (JmsActivation) activations.remove(spec);
+      if (activation != null)
+         activation.stop();
+   }
+   
+   public XAResource[] getXAResources(ActivationSpec[] specs) throws ResourceException
+   {
+      // TODO getXAResources
+      return null;
+   }
+   
+   public void start(BootstrapContext ctx) throws ResourceAdapterInternalException
+   {
+      this.ctx = ctx;
+   }
+
+   public void stop()
+   {
+      for (Iterator i = activations.entrySet().iterator(); i.hasNext();)
+      {
+         Map.Entry entry = (Map.Entry) i.next();
+         try
+         {
+            JmsActivation activation = (JmsActivation) entry.getValue();
+            if (activation != null)
+               activation.stop();
+         }
+         catch (Exception ignored)
+         {
+            log.debug("Ignored", ignored);
+         }
+         i.remove();
+      }
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSession.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSession.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSession.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,688 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.IllegalStateException;
+import javax.jms.InvalidDestinationException;
+import javax.jms.JMSException;
+import javax.jms.MessageListener;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.QueueBrowser;
+import javax.jms.QueueReceiver;
+import javax.jms.QueueSender;
+import javax.jms.QueueSession;
+import javax.jms.Session;
+import javax.jms.StreamMessage;
+import javax.jms.TemporaryQueue;
+import javax.jms.TemporaryTopic;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.jms.TopicPublisher;
+import javax.jms.TopicSession;
+import javax.jms.TopicSubscriber;
+import javax.resource.spi.ConnectionEvent;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Adapts the JMS QueueSession and TopicSession API to a JmsManagedConnection.
+ * 
+ * @author <a href="mailto:peter.antman at tim.se">Peter Antman </a>.
+ * @author <a href="mailto:jason at planet57.com">Jason Dillon </a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 63350 $
+ */
+public class JmsSession implements Session, QueueSession, TopicSession
+{
+   private static final Logger log = Logger.getLogger(JmsSession.class);
+
+   /** The managed connection for this session. */
+   private JmsManagedConnection mc; // = null;
+
+   /** The connection request info */
+   private JmsConnectionRequestInfo info;
+
+   /** The session factory for this session */
+   private JmsSessionFactory sf;
+   
+   /** The message consumers */
+   private HashSet consumers = new HashSet();
+   
+   /** The message producers */
+   private HashSet producers = new HashSet();
+   
+   /** Whether trace is enabled */
+   private boolean trace = log.isTraceEnabled();
+   
+   /**
+    * Construct a <tt>JmsSession</tt>.
+    * 
+    * @param mc The managed connection for this session.
+    */
+   public JmsSession(final JmsManagedConnection mc, JmsConnectionRequestInfo info)
+   {
+      this.mc = mc;
+      this.info = info;
+      if (trace)
+         log.trace("new JmsSession " + this + " mc=" + mc + " cri=" + info);
+   }
+
+   public void setJmsSessionFactory(JmsSessionFactory sf)
+   {
+      this.sf = sf;
+   }
+   
+   /**
+    * Ensure that the session is opened.
+    * 
+    * @return The session
+    * 
+    * @throws IllegalStateException The session is closed
+    */
+   Session getSession() throws JMSException
+   {
+      // ensure that the connection is opened
+      if (mc == null)
+         throw new IllegalStateException("The session is closed");
+      
+      Session session = mc.getSession();
+      if (trace)
+         log.trace("getSession " + session + " for " + this);
+      return session;
+   }
+
+   // ---- Session API
+
+   public BytesMessage createBytesMessage() throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createBytesMessage" + session);
+      return session.createBytesMessage();
+   }
+
+   public MapMessage createMapMessage() throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createMapMessage" + session);
+      return session.createMapMessage();
+   }
+
+   public Message createMessage() throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createMessage" + session);
+      return session.createMessage();
+   }
+
+   public ObjectMessage createObjectMessage() throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createObjectMessage" + session);
+      return session.createObjectMessage();
+   }
+
+   public ObjectMessage createObjectMessage(Serializable object) throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createObjectMessage(Object)" + session);
+      return session.createObjectMessage(object);
+   }
+
+   public StreamMessage createStreamMessage() throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createStreamMessage" + session);
+      return session.createStreamMessage();
+   }
+
+   public TextMessage createTextMessage() throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createTextMessage" + session);
+      return session.createTextMessage();
+   }
+
+   public TextMessage createTextMessage(String string) throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createTextMessage(String)" + session);
+      return session.createTextMessage(string);
+   }
+
+
+   public boolean getTransacted() throws JMSException
+   {
+      getSession(); // check closed
+      return info.isTransacted();
+   }
+
+   /**
+    * Always throws an Exception.
+    * 
+    * @throws IllegalStateException Method not allowed.
+    */
+   public MessageListener getMessageListener() throws JMSException
+   {
+      throw new IllegalStateException("Method not allowed");
+   }
+
+   /**
+    * Always throws an Exception.
+    * 
+    * @throws IllegalStateException Method not allowed.
+    */
+   public void setMessageListener(MessageListener listener) throws JMSException
+   {
+      throw new IllegalStateException("Method not allowed");
+   }
+
+   /**
+    * Always throws an Error.
+    * 
+    * @throws Error Method not allowed.
+    */
+   public void run()
+   {
+      // should this really throw an Error?
+      throw new Error("Method not allowed");
+   }
+
+   /**
+    * Closes the session. Sends a ConnectionEvent.CONNECTION_CLOSED to the
+    * managed connection.
+    * 
+    * @throws JMSException Failed to close session.
+    */
+   public void close() throws JMSException
+   {
+      sf.closeSession(this);
+      closeSession();
+   }
+
+   // FIXME - is this really OK, probably not
+   public void commit() throws JMSException
+   {
+      Session session = getSession();
+      if (info.isTransacted() == false)
+         throw new IllegalStateException("Session is not transacted");
+      if (trace)
+         log.trace("Commit session " + this);
+      session.commit();
+   }
+
+   public void rollback() throws JMSException
+   {
+      Session session = getSession();
+      if (info.isTransacted() == false)
+         throw new IllegalStateException("Session is not transacted");
+      if (trace)
+         log.trace("Rollback session " + this);
+      session.rollback();
+   }
+
+   public void recover() throws JMSException
+   {
+      Session session = getSession();
+      if (info.isTransacted())
+         throw new IllegalStateException("Session is transacted");
+      if (trace)
+         log.trace("Recover session " + this);
+      session.recover();
+   }
+
+   // --- TopicSession API
+
+   public Topic createTopic(String topicName) throws JMSException
+   {
+      if(info.getType() == JmsConnectionFactory.QUEUE)
+      {
+         throw new IllegalStateException("Cannot create topic for javax.jms.QueueSession");         
+      }
+
+      Session session = getSession();
+      if (trace)
+         log.trace("createTopic " + session + " topicName=" + topicName);
+      Topic result = session.createTopic(topicName);
+      if (trace)
+         log.trace("createdTopic " + session + " topic=" + result);
+      return result;
+   }
+
+   public TopicSubscriber createSubscriber(Topic topic) throws JMSException
+   {
+      TopicSession session = getTopicSession();
+      if (trace)
+         log.trace("createSubscriber " + session + " topic=" + topic);
+      TopicSubscriber result = session.createSubscriber(topic);
+      result = new JmsTopicSubscriber(result, this);
+      if (trace)
+         log.trace("createdSubscriber " + session + " JmsTopicSubscriber=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException
+   {
+      TopicSession session = getTopicSession();
+      if (trace)
+         log.trace("createSubscriber " + session + " topic=" + topic + " selector=" + messageSelector + " noLocal=" + noLocal);
+      TopicSubscriber result = session.createSubscriber(topic, messageSelector, noLocal);
+      result = new JmsTopicSubscriber(result, this);
+      if (trace)
+         log.trace("createdSubscriber " + session + " JmsTopicSubscriber=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException
+   {
+      if(info.getType() == JmsConnectionFactory.QUEUE)
+      {
+         throw new IllegalStateException("Cannot create durable subscriber from javax.jms.QueueSession");         
+      }
+      
+      Session session = getSession();
+      if (trace)
+         log.trace("createDurableSubscriber " + session + " topic=" + topic + " name=" + name);
+      TopicSubscriber result = session.createDurableSubscriber(topic, name);
+      result = new JmsTopicSubscriber(result, this);
+      if (trace)
+         log.trace("createdDurableSubscriber " + session + " JmsTopicSubscriber=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal)
+         throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createDurableSubscriber " + session + " topic=" + topic + " name=" + name + " selector=" + messageSelector + " noLocal=" + noLocal);
+      TopicSubscriber result = session.createDurableSubscriber(topic, name, messageSelector, noLocal);
+      result = new JmsTopicSubscriber(result, this);
+      if (trace)
+         log.trace("createdDurableSubscriber " + session + " JmsTopicSubscriber=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public TopicPublisher createPublisher(Topic topic) throws JMSException
+   {
+      TopicSession session = getTopicSession();
+      if (trace)
+         log.trace("createPublisher " + session + " topic=" + topic);
+      TopicPublisher result = session.createPublisher(topic);
+      if (trace)
+         log.trace("createdPublisher " + session + " publisher=" + result);
+      addProducer(result);
+      return result;
+   }
+
+   public TemporaryTopic createTemporaryTopic() throws JMSException
+   {
+      if(info.getType() == JmsConnectionFactory.QUEUE)
+      {
+         throw new IllegalStateException("Cannot create temporary topic for javax.jms.QueueSession");         
+      }
+      
+      Session session = getSession();
+      if (trace)
+         log.trace("createTemporaryTopic " + session);
+      TemporaryTopic temp = session.createTemporaryTopic();
+      if (trace)
+         log.trace("createdTemporaryTopic " + session + " temp=" + temp);
+      sf.addTemporaryTopic(temp);
+      return temp;
+   }
+
+   public void unsubscribe(String name) throws JMSException
+   {
+      if(info.getType() == JmsConnectionFactory.QUEUE)
+      {
+         throw new IllegalStateException("Cannot unsubscribe for javax.jms.QueueSession");         
+      }
+
+      Session session = getSession();
+      if (trace)
+         log.trace("unsubscribe " + session + " name=" + name);
+      session.unsubscribe(name);
+   }
+
+   //--- QueueSession API
+
+   public QueueBrowser createBrowser(Queue queue) throws JMSException
+   {
+      
+      if(info.getType() == JmsConnectionFactory.TOPIC)
+      {
+         throw new IllegalStateException("Cannot create browser for javax.jms.TopicSession");
+         
+      }
+
+      Session session = getSession();
+      if (trace)
+         log.trace("createBrowser " + session + " queue=" + queue);
+      QueueBrowser result = session.createBrowser(queue);
+      if (trace)
+         log.trace("createdBrowser " + session + " browser=" + result);
+      return result;
+   }
+
+   public QueueBrowser createBrowser(Queue queue, String messageSelector) throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createBrowser " + session + " queue=" + queue + " selector=" + messageSelector);
+      QueueBrowser result = session.createBrowser(queue, messageSelector);
+      if (trace)
+         log.trace("createdBrowser " + session + " browser=" + result);
+      return result;
+   }
+
+   public Queue createQueue(String queueName) throws JMSException
+   {
+      if(info.getType() == JmsConnectionFactory.TOPIC)
+      {
+         throw new IllegalStateException("Cannot create browser or javax.jms.TopicSession");
+         
+      }
+
+      Session session = getSession();
+      if (trace)
+         log.trace("createQueue " + session + " queueName=" + queueName);
+      Queue result = session.createQueue(queueName);
+      if (trace)
+         log.trace("createdQueue " + session + " queue=" + result);
+      return result;
+   }
+
+   public QueueReceiver createReceiver(Queue queue) throws JMSException
+   {
+      QueueSession session = getQueueSession();
+      if (trace)
+         log.trace("createReceiver " + session + " queue=" + queue);
+      QueueReceiver result = session.createReceiver(queue);
+      result = new JmsQueueReceiver(result, this);
+      if (trace)
+         log.trace("createdReceiver " + session + " receiver=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException
+   {
+      QueueSession session = getQueueSession();
+      if (trace)
+         log.trace("createReceiver " + session + " queue=" + queue + " selector=" + messageSelector);
+      QueueReceiver result = session.createReceiver(queue, messageSelector);
+      result = new JmsQueueReceiver(result, this);
+      if (trace)
+         log.trace("createdReceiver " + session + " receiver=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public QueueSender createSender(Queue queue) throws JMSException
+   {
+      QueueSession session = getQueueSession();
+      if (trace)
+         log.trace("createSender " + session + " queue=" + queue);
+      QueueSender result = session.createSender(queue);
+      if (trace)
+         log.trace("createdSender " + session + " sender=" + result);
+      addProducer(result);
+      return result;
+   }
+
+   public TemporaryQueue createTemporaryQueue() throws JMSException
+   {
+      if(info.getType() == JmsConnectionFactory.TOPIC)
+      {
+         throw new IllegalStateException("Cannot create temporary queue for javax.jms.TopicSession");
+         
+      }
+      Session session = getSession();
+      if (trace)
+         log.trace("createTemporaryQueue " + session);
+      TemporaryQueue temp = session.createTemporaryQueue();
+      if (trace)
+         log.trace("createdTemporaryQueue " + session + " temp=" + temp);
+      sf.addTemporaryQueue(temp);
+      return temp;
+   }
+
+   // -- JMS 1.1
+
+   public MessageConsumer createConsumer(Destination destination) throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createConsumer " + session + " dest=" + destination);
+      MessageConsumer result = session.createConsumer(destination);
+      result = new JmsMessageConsumer(result, this);
+      if (trace)
+         log.trace("createdConsumer " + session + " consumer=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createConsumer " + session + " dest=" + destination + " messageSelector=" + messageSelector);
+      MessageConsumer result = session.createConsumer(destination, messageSelector);
+      result = new JmsMessageConsumer(result, this);
+      if (trace)
+         log.trace("createdConsumer " + session + " consumer=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal)
+         throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createConsumer " + session + " dest=" + destination + " messageSelector=" + messageSelector + " noLocal=" + noLocal);
+      MessageConsumer result = session.createConsumer(destination, messageSelector, noLocal);
+      result = new JmsMessageConsumer(result, this);
+      if (trace)
+         log.trace("createdConsumer " + session + " consumer=" + result);
+      addConsumer(result);
+      return result;
+   }
+
+   public MessageProducer createProducer(Destination destination) throws JMSException
+   {
+      Session session = getSession();
+      if (trace)
+         log.trace("createProducer " + session + " dest=" + destination);
+      MessageProducer result = getSession().createProducer(destination);
+      if (trace)
+         log.trace("createdProducer " + session + " producer=" + result);
+      addProducer(result);
+      return result;
+   }
+
+   public int getAcknowledgeMode() throws JMSException
+   {
+      getSession(); // check closed
+      return info.getAcknowledgeMode();
+   }
+
+   // --- JmsManagedConnection api
+
+   void setManagedConnection(final JmsManagedConnection mc)
+   {
+      if (this.mc != null)
+         this.mc.removeHandle(this);
+      this.mc = mc;
+   }
+
+   void destroy()
+   {
+      mc = null;
+   }
+
+   void start() throws JMSException
+   {
+      if (mc != null)
+         mc.start();
+   }
+
+   void stop() throws JMSException
+   {
+      if (mc != null)
+         mc.stop();
+   }
+
+   void checkStrict() throws JMSException
+   {
+      if (mc != null && mc.getManagedConnectionFactory().isStrict())
+         throw new IllegalStateException(JmsSessionFactory.ISE);
+   }
+   
+   void closeSession() throws JMSException
+   {
+      if (mc != null)
+      {
+         log.trace("Closing session");
+
+         try
+         {
+            mc.stop();
+         }
+         catch (Throwable t)
+         {
+            log.trace("Error stopping managed connection", t);
+         }
+         
+         synchronized (consumers)
+         {
+            for (Iterator i = consumers.iterator(); i.hasNext();)
+            {
+               JmsMessageConsumer consumer = (JmsMessageConsumer) i.next();
+               try
+               {
+                  consumer.closeConsumer();
+               }
+               catch (Throwable t)
+               {
+                  log.trace("Error closing consumer", t);
+               }
+               i.remove();
+            }
+         }
+
+         synchronized (producers)
+         {
+            for (Iterator i = producers.iterator(); i.hasNext();)
+            {
+               MessageProducer producer = (MessageProducer) i.next();
+               try
+               {
+                  producer.close();
+               }
+               catch (Throwable t)
+               {
+                  log.trace("Error closing producer", t);
+               }
+               i.remove();
+            }
+         }
+         
+         mc.removeHandle(this);
+         ConnectionEvent ev = new ConnectionEvent(mc, ConnectionEvent.CONNECTION_CLOSED);
+         ev.setConnectionHandle(this);
+         mc.sendEvent(ev);
+         mc = null;
+      }
+   }
+   
+   void addConsumer(MessageConsumer consumer)
+   {
+      synchronized (consumers)
+      {
+         consumers.add(consumer);
+      }
+   }
+   
+   void removeConsumer(MessageConsumer consumer)
+   {
+      synchronized (consumers)
+      {
+         consumers.remove(consumer);
+      }
+   }
+   
+   void addProducer(MessageProducer producer)
+   {
+      synchronized (producers)
+      {
+         producers.add(producer);
+      }
+   }
+   
+   void removeProducer(MessageProducer producer)
+   {
+      synchronized (producers)
+      {
+         producers.remove(producer);
+      }
+   }
+   
+   QueueSession getQueueSession() throws JMSException
+   {
+      Session s = getSession();
+      if( !(s instanceof QueueSession) )
+         throw new InvalidDestinationException("Attempting to use QueueSession methods on: "+this);
+      return (QueueSession) s; 
+   }
+   
+   TopicSession getTopicSession() throws JMSException
+   {
+      Session s = getSession();
+      if( !(s instanceof TopicSession) )
+         throw new InvalidDestinationException("Attempting to use TopicSession methods on: "+this);
+      return (TopicSession) s; 
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSessionFactory.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSessionFactory.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSessionFactory.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.QueueConnection;
+import javax.jms.TemporaryQueue;
+import javax.jms.TemporaryTopic;
+import javax.jms.TopicConnection;
+
+/**
+ * A marker interface to join topics and queues into one factory.
+ *
+ * @author  <a href="mailto:peter.antman at tim.se">Peter Antman</a>.
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version <pre>$Revision: 57189 $</pre>
+ */
+public interface JmsSessionFactory
+   extends Connection, TopicConnection, QueueConnection
+{
+   /** Error message for strict behaviour */
+   String ISE = "This method is not applicable inside the application server. See the J2EE spec, e.g. J2EE1.4 Section 6.6";
+
+   /**
+    * Add a temporary queue
+    * 
+    * @param temp the temporary queue
+    */
+   void addTemporaryQueue(TemporaryQueue temp);
+
+   /**
+    * Add a temporary topic
+    * 
+    * @param temp the temporary topic
+    */
+   void addTemporaryTopic(TemporaryTopic temp);
+   
+   /** 
+    * Notification that a session is closed
+    * 
+    * @throws JMSException for any error 
+    */
+   void closeSession(JmsSession session) throws JMSException;
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSessionFactoryImpl.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSessionFactoryImpl.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsSessionFactoryImpl.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,415 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import javax.jms.ConnectionConsumer;
+import javax.jms.ConnectionMetaData;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.IllegalStateException;
+import javax.jms.JMSException;
+import javax.jms.Queue;
+import javax.jms.QueueSession;
+import javax.jms.ServerSessionPool;
+import javax.jms.Session;
+import javax.jms.TemporaryQueue;
+import javax.jms.TemporaryTopic;
+import javax.jms.Topic;
+import javax.jms.TopicSession;
+import javax.naming.Reference;
+import javax.resource.Referenceable;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ManagedConnectionFactory;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Implements the JMS Connection API and produces {@link JmsSession} objects.
+ *
+ * @author  <a href="mailto:peter.antman at tim.se">Peter Antman</a>.
+ * @author  <a href="mailto:jason at planet57.com">Jason Dillon</a>
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version <tt>$Revision: 57189 $</tt>
+ */
+public class JmsSessionFactoryImpl
+   implements JmsSessionFactory, Referenceable
+{
+   private static final Logger log = Logger.getLogger(JmsSessionFactoryImpl.class);
+
+   /** Are we closed? */
+   private boolean closed = false;
+
+   /** Whether trace is enabled */
+   private boolean trace = log.isTraceEnabled();
+   
+   private Reference reference;
+
+   // Used from JmsConnectionFactory
+   private String userName;
+   private String password;
+   private String clientID;
+   private int type;
+
+   /* Whether we are started */
+   private boolean started = false;
+   
+   /** JmsRa own factory */
+   private JmsManagedConnectionFactory mcf;
+
+   /** Hook to the appserver */
+   private ConnectionManager cm;
+
+   /** The sessions */
+   private HashSet sessions = new HashSet();
+
+   /** The temporary queues */
+   private HashSet tempQueues = new HashSet();
+
+   /** The temporary topics */
+   private HashSet tempTopics = new HashSet();
+   
+   public JmsSessionFactoryImpl(final ManagedConnectionFactory mcf,
+                                final ConnectionManager cm,
+                                final int type)
+   {
+      this.mcf = (JmsManagedConnectionFactory) mcf;
+      this.cm = cm;
+      
+      if (cm == null)
+         // This is standalone usage, no appserver
+         this.cm = new JmsConnectionManager();
+      else 
+         this.cm = cm;
+
+      this.type = type;
+
+      if (trace)
+         log.trace("mcf=" + mcf + ", cm=" + cm + ", type=" + type);
+   }
+
+   public void setReference(final Reference reference)
+   {
+      this.reference = reference;
+   }
+    
+   public Reference getReference()
+   {
+      return reference;
+   }
+    
+   // --- API for JmsConnectionFactoryImpl
+   
+   public void setUserName(final String name) 
+   {
+      userName = name;
+   }
+    
+   public void setPassword(final String password) 
+   {
+      this.password = password;
+   }
+
+   //---- QueueConnection ---
+   
+   public QueueSession createQueueSession(final boolean transacted, 
+                                          final int acknowledgeMode) 
+      throws JMSException
+   {
+      checkClosed();
+      if (type == JmsConnectionFactory.TOPIC)
+         throw new IllegalStateException("Can not get a queue session from a topic connection");
+      return allocateConnection(transacted, acknowledgeMode, type);
+   }
+    
+   public ConnectionConsumer createConnectionConsumer
+      (Queue queue,
+       String messageSelector,
+       ServerSessionPool sessionPool,
+       int maxMessages) 
+      throws JMSException 
+   {
+      throw new IllegalStateException(ISE);
+   }
+    
+   //--- TopicConnection ---
+    
+   public TopicSession createTopicSession(final boolean transacted, 
+                                          final int acknowledgeMode) 
+      throws JMSException
+   { 
+      checkClosed();
+      if (type == JmsConnectionFactory.QUEUE)
+         throw new IllegalStateException("Can not get a topic session from a queue connection");
+      return allocateConnection(transacted, acknowledgeMode, type);
+   }
+
+   public ConnectionConsumer createConnectionConsumer
+      (Topic topic,
+       String messageSelector,
+       ServerSessionPool sessionPool,
+       int maxMessages) 
+      throws JMSException 
+   {
+      throw new IllegalStateException(ISE);
+   }		       
+
+   public ConnectionConsumer createDurableConnectionConsumer(
+      Topic topic, 
+      String subscriptionName,
+      String messageSelector,
+      ServerSessionPool sessionPool, 
+      int maxMessages) 
+      throws JMSException
+   {
+      throw new IllegalStateException(ISE);
+   }
+   
+   //--- All the Connection methods
+   
+   public String getClientID() throws JMSException
+   {
+      checkClosed();
+      return clientID;
+   }
+    
+   public void setClientID(String cID) throws JMSException
+   {
+      if (mcf.isStrict())
+         throw new IllegalStateException(ISE);
+      
+      checkClosed();
+      if (clientID != null)
+         throw new IllegalStateException("Cannot change client id");
+      clientID = cID;
+   }
+    
+   public ConnectionMetaData getMetaData() throws JMSException
+   {
+      checkClosed();
+      return mcf.getMetaData();
+   }
+    
+   public ExceptionListener getExceptionListener() throws JMSException
+   {
+      throw new IllegalStateException(ISE);
+   }
+    
+   public void setExceptionListener(ExceptionListener listener)
+      throws JMSException
+   {
+      throw new IllegalStateException(ISE);
+   }
+    
+   public void start() throws JMSException
+   {
+      checkClosed();
+      if (trace)
+         log.trace("start() " + this);
+      synchronized (sessions)
+      {
+         if (started)
+            return;
+         started = true;
+         for (Iterator i = sessions.iterator(); i.hasNext();)
+         {
+            JmsSession session = (JmsSession) i.next();
+            session.start();
+         }
+      }
+   }
+    
+   public void stop() throws JMSException
+   {
+      if (mcf.isStrict())
+         throw new IllegalStateException(ISE);
+      checkClosed();
+      if (trace)
+         log.trace("stop() " + this);
+      synchronized (sessions)
+      {
+         if (started == false)
+            return;
+         started = true;
+         for (Iterator i = sessions.iterator(); i.hasNext();)
+         {
+            JmsSession session = (JmsSession) i.next();
+            session.stop();
+         }
+      }
+   }
+
+   public void close() throws JMSException
+   {
+      if (closed)
+         return;
+      closed = true;
+
+      if (trace)
+         log.trace("close() " + this);
+      
+      synchronized (sessions)
+      {
+         for (Iterator i = sessions.iterator(); i.hasNext();)
+         {
+            JmsSession session = (JmsSession) i.next();
+            try
+            {
+               session.closeSession();
+            }
+            catch (Throwable t)
+            {
+               log.trace("Error closing session", t);
+            }
+            i.remove();
+         }
+      }
+      
+      synchronized (tempQueues)
+      {
+         for (Iterator i = tempQueues.iterator(); i.hasNext();)
+         {
+            TemporaryQueue temp = (TemporaryQueue) i.next();
+            try
+            {
+               if (trace)
+                  log.trace("Closing temporary queue " + temp + " for " + this);
+               temp.delete();
+            }
+            catch (Throwable t)
+            {
+               log.trace("Error deleting temporary queue", t);
+            }
+            i.remove();
+         }
+      }
+      
+      synchronized (tempTopics)
+      {
+         for (Iterator i = tempTopics.iterator(); i.hasNext();)
+         {
+            TemporaryTopic temp = (TemporaryTopic) i.next();
+            try
+            {
+               if (trace)
+                  log.trace("Closing temporary topic " + temp + " for " + this);
+               temp.delete();
+            }
+            catch (Throwable t)
+            {
+               log.trace("Error deleting temporary queue", t);
+            }
+            i.remove();
+         }
+      }
+   }
+
+   public void closeSession(JmsSession session) throws JMSException
+   {
+      synchronized (sessions)
+      {
+         sessions.remove(session);
+      }
+   }
+   
+   public void addTemporaryQueue(TemporaryQueue temp)
+   {
+      synchronized(tempQueues)
+      {
+         tempQueues.add(temp);
+      }
+   }
+   
+   public void addTemporaryTopic(TemporaryTopic temp)
+   {
+      synchronized(tempTopics)
+      {
+         tempTopics.add(temp);
+      }
+   }
+   
+   // -- JMS 1.1
+
+   public ConnectionConsumer createConnectionConsumer(Destination destination, ServerSessionPool pool, int maxMessages) throws JMSException
+   {
+      throw new IllegalStateException(ISE);
+   }
+
+   public ConnectionConsumer createConnectionConsumer(Destination destination, String name, ServerSessionPool pool, int maxMessages) throws JMSException
+   {
+      throw new IllegalStateException(ISE);
+   }
+
+   public Session createSession(boolean transacted, int acknowledgeMode)
+      throws JMSException
+   {
+      checkClosed();
+      return allocateConnection(transacted, acknowledgeMode, type);
+   }
+
+   protected JmsSession allocateConnection(boolean transacted, int acknowledgeMode, int sessionType) throws JMSException
+   {
+      try
+      {
+         synchronized (sessions)
+         {
+            if (mcf.isStrict() && sessions.isEmpty() == false)
+               throw new IllegalStateException("Only allowed one session per connection. See the J2EE spec, e.g. J2EE1.4 Section 6.6");
+            if (transacted)
+               acknowledgeMode = Session.SESSION_TRANSACTED;
+            JmsConnectionRequestInfo info = new JmsConnectionRequestInfo(transacted, acknowledgeMode, sessionType);
+            info.setUserName(userName);
+            info.setPassword(password);
+            info.setClientID(clientID);
+
+            if (trace)
+               log.trace("Allocating session for " + this + " with request info=" + info);
+            JmsSession session = (JmsSession) cm.allocateConnection(mcf, info);
+            if (trace)
+               log.trace("Allocated  " + this + " session=" + session);
+            session.setJmsSessionFactory(this);
+            if (started)
+               session.start();
+            sessions.add(session);
+            return session;
+         }
+      }
+      catch (ResourceException e)
+      {
+         log.error("could not create session", e);
+         
+         JMSException je = new JMSException
+            ("Could not create a session: " + e);
+         je.setLinkedException(e);
+         throw je;
+      }               
+   }  
+
+   protected void checkClosed() throws IllegalStateException
+   {
+      if (closed)
+         throw new IllegalStateException("The connection is closed");
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsStreamMessage.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsStreamMessage.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsStreamMessage.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,165 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.JMSException;
+import javax.jms.StreamMessage;
+
+/**
+ * A wrapper for a message
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsStreamMessage extends JmsMessage implements StreamMessage
+{
+   /**
+    * Create a new wrapper
+    * 
+    * @param message the message
+    * @param session the session
+    */
+   public JmsStreamMessage(StreamMessage message, JmsSession session)
+   {
+      super(message, session);
+   }
+   
+   public boolean readBoolean() throws JMSException
+   {
+      return ((StreamMessage) message).readBoolean();
+   }
+   
+   public byte readByte() throws JMSException
+   {
+      return ((StreamMessage) message).readByte();
+   }
+   
+   public int readBytes(byte[] value) throws JMSException
+   {
+      return ((StreamMessage) message).readBytes(value);
+   }
+   
+   public char readChar() throws JMSException
+   {
+      return ((StreamMessage) message).readChar();
+   }
+   
+   public double readDouble() throws JMSException
+   {
+      return ((StreamMessage) message).readDouble();
+   }
+   
+   public float readFloat() throws JMSException
+   {
+      return ((StreamMessage) message).readFloat();
+   }
+   
+   public int readInt() throws JMSException
+   {
+      return ((StreamMessage) message).readInt();
+   }
+   
+   public long readLong() throws JMSException
+   {
+      return ((StreamMessage) message).readLong();
+   }
+   
+   public Object readObject() throws JMSException
+   {
+      return ((StreamMessage) message).readObject();
+   }
+   
+   public short readShort() throws JMSException
+   {
+      return ((StreamMessage) message).readShort();
+   }
+   
+   public String readString() throws JMSException
+   {
+      return ((StreamMessage) message).readString();
+   }
+   
+   public void reset() throws JMSException
+   {
+      ((StreamMessage) message).reset();
+   }
+   
+   public void writeBoolean(boolean value) throws JMSException
+   {
+      ((StreamMessage) message).writeBoolean(value);
+   }
+   
+   public void writeByte(byte value) throws JMSException
+   {
+      ((StreamMessage) message).writeByte(value);
+   }
+   
+   public void writeBytes(byte[] value, int offset, int length) throws JMSException
+   {
+      ((StreamMessage) message).writeBytes(value, offset, length);
+   }
+   
+   public void writeBytes(byte[] value) throws JMSException
+   {
+      ((StreamMessage) message).writeBytes(value);
+   }
+   
+   public void writeChar(char value) throws JMSException
+   {
+      ((StreamMessage) message).writeChar(value);
+   }
+   
+   public void writeDouble(double value) throws JMSException
+   {
+      ((StreamMessage) message).writeDouble(value);
+   }
+
+   public void writeFloat(float value) throws JMSException
+   {
+      ((StreamMessage) message).writeFloat(value);
+   }
+
+   public void writeInt(int value) throws JMSException
+   {
+      ((StreamMessage) message).writeInt(value);
+   }
+
+   public void writeLong(long value) throws JMSException
+   {
+      ((StreamMessage) message).writeLong(value);
+   }
+
+   public void writeObject(Object value) throws JMSException
+   {
+      ((StreamMessage) message).writeObject(value);
+   }
+
+   public void writeShort(short value) throws JMSException
+   {
+      ((StreamMessage) message).writeShort(value);
+   }
+
+   public void writeString(String value) throws JMSException
+   {
+      ((StreamMessage) message).writeString(value);
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsTextMessage.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsTextMessage.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsTextMessage.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+
+/**
+ * A wrapper for a message
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsTextMessage extends JmsMessage implements TextMessage
+{
+   /**
+    * Create a new wrapper
+    * 
+    * @param message the message
+    * @param session the session
+    */
+   public JmsTextMessage(TextMessage message, JmsSession session)
+   {
+      super(message, session);
+   }
+
+   public String getText() throws JMSException
+   {
+      return ((TextMessage) message).getText();
+   }
+   
+   public void setText(String string) throws JMSException
+   {
+      ((TextMessage) message).setText(string);
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsTopicSubscriber.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsTopicSubscriber.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/JmsTopicSubscriber.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms;
+
+import javax.jms.JMSException;
+import javax.jms.Topic;
+import javax.jms.TopicSubscriber;
+
+/**
+ * A wrapper for a topic subscriber
+ *
+ * @author <a href="mailto:adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JmsTopicSubscriber extends JmsMessageConsumer implements TopicSubscriber
+{
+   /**
+    * Create a new wrapper
+    * 
+    * @param consumer the topic subscriber
+    * @param session the session
+    */
+   public JmsTopicSubscriber(TopicSubscriber consumer, JmsSession session)
+   {
+      super(consumer, session);
+   }
+
+   public boolean getNoLocal() throws JMSException
+   {
+      return ((TopicSubscriber) consumer).getNoLocal();
+   }
+
+   public Topic getTopic() throws JMSException
+   {
+      return ((TopicSubscriber) consumer).getTopic();
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/DLQHandler.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/DLQHandler.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/DLQHandler.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow;
+
+import javax.jms.Message;
+import javax.naming.Context;
+
+/**
+ * An interface for DLQ Handling
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public interface DLQHandler
+{
+   /** JMS property name holding original destination. */
+   static final String JBOSS_ORIG_DESTINATION = "JBOSS_ORIG_DESTINATION";
+
+   /** JMS property name holding original JMS message id. */
+   static final String JBOSS_ORIG_MESSAGEID = "JBOSS_ORIG_MESSAGEID";
+
+   /** Standard property for delivery count */
+   static final String PROPERTY_DELIVERY_COUNT = "JMSXDeliveryCount";
+
+   /**
+    * Set up the DLQ
+    * 
+    * @param activation the activation
+    * @param ctx the naming context
+    * @throws Exception for any error
+    */
+   void setup(JmsActivation activation, Context ctx) throws Exception;
+
+   /**
+    * Tear down the DLQ
+    */
+   void teardown();
+   
+   /**
+    * Check whether the DLQ should handle the message
+    * 
+    * @param msg the message about to be delivered
+    * @return true if the message is handled and should not be delivered
+    */
+   boolean handleRedeliveredMessage(Message msg);
+   
+   /**
+    * Notification that the message was delivered
+    * 
+    * @param msg the message that was delivered
+    */
+   void messageDelivered(Message msg);
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsActivation.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsActivation.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsActivation.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,597 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow;
+
+import java.lang.reflect.Method;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.XAQueueConnectionFactory;
+import javax.jms.XATopicConnectionFactory;
+import javax.naming.Context;
+import javax.resource.ResourceException;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.resource.spi.work.Work;
+import javax.resource.spi.work.WorkManager;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.jndi.JMSProviderAdapter;
+import org.jboss.logging.Logger;
+import org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.JmsResourceAdapter;
+import org.jboss.tm.TransactionManagerLocator;
+import org.jboss.util.Strings;
+import org.jboss.util.naming.Util;
+
+import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
+
+/**
+ * A generic jms Activation.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 60397 $
+ */
+public class JmsActivation implements ExceptionListener
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(JmsActivation.class);
+   
+   /** The onMessage method */
+   public static final Method ONMESSAGE; 
+   
+   /** The resource adapter */
+   protected JmsResourceAdapter ra;
+   
+   /** The activation spec */
+   protected JmsActivationSpec spec;
+
+   /** The message endpoint factory */
+   protected MessageEndpointFactory endpointFactory;
+   
+   /** Whether delivery is active */
+   protected SynchronizedBoolean deliveryActive;
+   
+   /** The jms provider adapter */
+   protected JMSProviderAdapter adapter;
+   
+   /** The destination */
+   protected Destination destination;
+   
+   /** The connection */
+   protected Connection connection;
+   
+   /** The server session pool */
+   protected JmsServerSessionPool pool;
+   
+   /** Is the delivery transacted */
+   protected boolean isDeliveryTransacted;
+   
+   /** The DLQ handler */
+   protected DLQHandler dlqHandler;
+   
+   /** The TransactionManager */
+   protected TransactionManager tm;
+   
+   
+   static
+   {
+      try
+      {
+         ONMESSAGE = MessageListener.class.getMethod("onMessage", new Class[] { Message.class });
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   public JmsActivation(JmsResourceAdapter ra, MessageEndpointFactory endpointFactory, JmsActivationSpec spec) throws ResourceException
+   {
+      this.ra = ra;
+      this.endpointFactory = endpointFactory;
+      this.spec = spec;
+      try
+      {
+         this.isDeliveryTransacted = endpointFactory.isDeliveryTransacted(ONMESSAGE);
+      }
+      catch (Exception e)
+      {
+         throw new ResourceException(e);
+      }
+   }
+
+   /**
+    * @return the activation spec
+    */
+   public JmsActivationSpec getActivationSpec()
+   {
+      return spec;
+   }
+
+   /**
+    * @return the message endpoint factory
+    */
+   public MessageEndpointFactory getMessageEndpointFactory()
+   {
+      return endpointFactory;
+   }
+
+   /**
+    * @return whether delivery is transacted
+    */
+   public boolean isDeliveryTransacted()
+   {
+      return isDeliveryTransacted;
+   }
+
+   /**
+    * @return the work manager
+    */
+   public WorkManager getWorkManager()
+   {
+      return ra.getWorkManager();
+   }
+   
+   public TransactionManager getTransactionManager()
+   {
+      if (tm == null)
+      {
+         tm = TransactionManagerLocator.getInstance().locate();
+
+      }
+
+      return tm;
+   }
+
+   /**
+    * @return the connection
+    */
+   public Connection getConnection()
+   {
+      return connection;
+   }
+
+   /**
+    * @return the destination
+    */
+   public Destination getDestination()
+   {
+      return destination;
+   }
+   
+   /**
+    * @return the provider adapter 
+    */
+   public JMSProviderAdapter getProviderAdapter()
+   {
+      return adapter; 
+   }
+   
+   /**
+    * @return the dlq handler 
+    */
+   public DLQHandler getDLQHandler()
+   {
+      return dlqHandler; 
+   }
+   
+   /**
+    * Start the activation
+    * 
+    * @throws ResourceException for any error
+    */
+   public void start() throws ResourceException
+   {
+      deliveryActive = new SynchronizedBoolean(true);
+      ra.getWorkManager().scheduleWork(new SetupActivation());
+   }
+
+   /**
+    * Stop the activation
+    */
+   public void stop()
+   {
+      deliveryActive.set(false);
+      teardown();
+   }
+
+   /**
+    * Handles any failure by trying to reconnect
+    */
+   public void handleFailure(Throwable failure)
+   {
+      log.warn("Failure in jms activation " + spec, failure);
+      
+      while (deliveryActive.get())
+      {
+         teardown();
+         try
+         {
+            Thread.sleep(spec.getReconnectIntervalLong());
+         }
+         catch (InterruptedException e)
+         {
+            log.debug("Interrupted trying to reconnect " + spec, e);
+            break;
+         }
+
+         log.info("Attempting to reconnect " + spec);
+         try
+         {
+            setup();
+            log.info("Reconnected with messaging provider.");            
+            break;
+         }
+         catch (Throwable t)
+         {
+            log.error("Unable to reconnect " + spec, t);
+         }
+         
+
+      }
+   }
+
+   public void onException(JMSException exception)
+   {
+      handleFailure(exception);
+   }
+
+   public String toString()
+   {
+      StringBuffer buffer = new StringBuffer();
+      buffer.append(Strings.defaultToString(this)).append('(');
+      buffer.append("spec=").append(Strings.defaultToString(spec));
+      buffer.append(" mepf=").append(Strings.defaultToString(endpointFactory));
+      buffer.append(" active=").append(deliveryActive.get());
+      if (destination != null)
+         buffer.append(" destination=").append(destination);
+      if (connection != null)
+         buffer.append(" connection=").append(connection);
+      if (pool != null)
+         buffer.append(" pool=").append(Strings.defaultToString(pool));
+      if (dlqHandler != null)
+         buffer.append(" dlq=").append(Strings.defaultToString(dlqHandler));
+      buffer.append(" transacted=").append(isDeliveryTransacted);
+      buffer.append(')');
+      return buffer.toString();
+   }
+
+   /**
+    * Setup the activation
+    * 
+    * @throws Exception for any error
+    */
+   protected void setup() throws Exception
+   {
+      log.debug("Setting up " + spec);
+
+      setupJMSProviderAdapter();
+      Context ctx = adapter.getInitialContext();
+      log.debug("Using context " + ctx.getEnvironment() + " for " + spec);
+      try
+      {
+         setupDLQ(ctx);
+         setupDestination(ctx);
+         setupConnection(ctx);
+      }
+      finally
+      {
+         ctx.close();
+      }
+      setupSessionPool();
+      
+      log.debug("Setup complete " + this);
+   }
+   
+   /**
+    * Teardown the activation
+    */
+   protected void teardown()
+   {
+      log.debug("Tearing down " + spec);
+
+      teardownSessionPool();
+      teardownConnection();
+      teardownDestination();
+      teardownDLQ();
+
+      log.debug("Tearing down complete " + this);
+   }
+
+   /**
+    * Get the jms provider
+    */
+   protected void setupJMSProviderAdapter() throws Exception
+   {
+      String providerAdapterJNDI = spec.getProviderAdapterJNDI();
+      if (providerAdapterJNDI.startsWith("java:") == false)
+         providerAdapterJNDI = "java:" + providerAdapterJNDI;
+
+      log.debug("Retrieving the jms provider adapter " + providerAdapterJNDI + " for " + this);
+      adapter = (JMSProviderAdapter) Util.lookup(providerAdapterJNDI, JMSProviderAdapter.class);
+      log.debug("Using jms provider adapter " + adapter + " for " + this);
+   }
+   
+   /**
+    * Setup the DLQ
+    *
+    * @param ctx the naming context
+    * @throws Exception for any error
+    */
+   protected void setupDLQ(Context ctx) throws Exception
+   {
+      if (spec.isUseDLQ())
+      {
+         Class clazz = Thread.currentThread().getContextClassLoader().loadClass(spec.getDLQHandler());
+         dlqHandler = (DLQHandler) clazz.newInstance();
+         dlqHandler.setup(this, ctx);
+      }
+      
+      log.debug("Setup DLQ " + this);
+   }
+   
+   /**
+    * Teardown the DLQ
+    */
+   protected void teardownDLQ()
+   {
+      log.debug("Removing DLQ " + this);
+      try
+      {
+         if (dlqHandler != null)
+            dlqHandler.teardown();
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error tearing down the DLQ " + dlqHandler, t);
+      }
+      dlqHandler = null;
+   }
+   
+   /**
+    * Setup the Destination
+    *
+    * @param ctx the naming context
+    * @throws Exception for any error
+    */
+   protected void setupDestination(Context ctx) throws Exception
+   {
+      Class destinationType;
+      if (spec.isTopic())
+         destinationType = Topic.class;
+      else
+         destinationType = Queue.class;
+
+      String destinationName = spec.getDestination();
+      log.debug("Retrieving destination " + destinationName + " of type " + destinationType.getName());
+      destination = (Destination) Util.lookup(ctx, destinationName, destinationType);
+      log.debug("Got destination " + destination + " from " + destinationName);
+   }
+   
+   /**
+    * Teardown the destination
+    */
+   protected void teardownDestination()
+   {
+   }
+   
+   /**
+    * Setup the Connection
+    *
+    * @param ctx the naming context
+    * @throws Exception for any error
+    */
+   protected void setupConnection(Context ctx) throws Exception
+   {
+      log.debug("setup connection " + this);
+
+      String user = spec.getUser();
+      String pass = spec.getPassword();
+      String clientID = spec.getClientId();
+      if (spec.isTopic())
+         connection = setupTopicConnection(ctx, user, pass, clientID);
+      else
+         connection = setupQueueConnection(ctx, user, pass, clientID);
+      
+      log.debug("established connection " + this);
+   }
+   
+   /**
+    * Setup a Queue Connection
+    *
+    * @param ctx the naming context
+    * @param user the user
+    * @param pass the password
+    * @param clientID the client id
+    * @throws Exception for any error
+    */
+   protected QueueConnection setupQueueConnection(Context ctx, String user, String pass, String clientID) throws Exception
+   {
+      String queueFactoryRef = adapter.getQueueFactoryRef();
+      log.debug("Attempting to lookup queue connection factory " + queueFactoryRef);
+      QueueConnectionFactory qcf = (QueueConnectionFactory) Util.lookup(ctx, queueFactoryRef, QueueConnectionFactory.class);
+      log.debug("Got queue connection factory " + qcf + " from " + queueFactoryRef);
+      log.debug("Attempting to create queue connection with user " + user);
+      QueueConnection result;
+      if (qcf instanceof XAQueueConnectionFactory && isDeliveryTransacted)
+      {
+         XAQueueConnectionFactory xaqcf = (XAQueueConnectionFactory) qcf;
+         if (user != null)
+            result = xaqcf.createXAQueueConnection(user, pass);
+         else
+            result = xaqcf.createXAQueueConnection();
+      }
+      else
+      {
+         if (user != null)
+            result = qcf.createQueueConnection(user, pass);
+         else
+            result = qcf.createQueueConnection();
+      }
+      if (clientID != null)
+         result.setClientID(clientID);
+      result.setExceptionListener(this);
+      log.debug("Using queue connection " + result);
+      return result;
+   }
+   
+   /**
+    * Setup a Topic Connection
+    *
+    * @param ctx the naming context
+    * @param user the user
+    * @param pass the password
+    * @param clientID the client id
+    * @throws Exception for any error
+    */
+   protected TopicConnection setupTopicConnection(Context ctx, String user, String pass, String clientID) throws Exception
+   {
+      String topicFactoryRef = adapter.getTopicFactoryRef();
+      log.debug("Attempting to lookup topic connection factory " + topicFactoryRef);
+      TopicConnectionFactory tcf = (TopicConnectionFactory) Util.lookup(ctx, topicFactoryRef, TopicConnectionFactory.class);
+      log.debug("Got topic connection factory " + tcf + " from " + topicFactoryRef);
+      log.debug("Attempting to create topic connection with user " + user);
+      TopicConnection result;
+      if (tcf instanceof XATopicConnectionFactory && isDeliveryTransacted)
+      {
+         XATopicConnectionFactory xatcf = (XATopicConnectionFactory) tcf;
+         if (user != null)
+            result = xatcf.createXATopicConnection(user, pass);
+         else
+            result = xatcf.createXATopicConnection();
+      }
+      else
+      {
+         if (user != null)
+            result = tcf.createTopicConnection(user, pass);
+         else
+            result = tcf.createTopicConnection();
+      }
+      if (clientID != null)
+         result.setClientID(clientID);
+      result.setExceptionListener(this);
+      log.debug("Using topic connection " + result);
+      return result;
+   }
+   
+   /**
+    * Teardown the connection
+    */
+   protected void teardownConnection()
+   {
+      try
+      {
+         if (connection != null)
+         {
+            log.debug("Closing the " + connection);
+            connection.close();
+         }
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error closing the connection " + connection, t);
+      }
+      connection = null;
+   }
+   
+   /**
+    * Setup the server session pool
+    * 
+    * @throws Exception for any error
+    */
+   protected void setupSessionPool() throws Exception
+   {
+      pool = new JmsServerSessionPool(this);
+      log.debug("Created session pool " + pool);
+      
+      log.debug("Starting session pool " + pool);
+      pool.start();
+      log.debug("Started session pool " + pool);
+      
+      log.debug("Starting delivery " + connection);
+      connection.start();
+      log.debug("Started delivery " + connection);
+   }
+   
+   /**
+    * Teardown the server session pool
+    */
+   protected void teardownSessionPool()
+   {
+      try
+      {
+         if (connection != null)
+         {
+            log.debug("Stopping delivery " + connection);
+            connection.stop();
+         }
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error stopping delivery " + connection, t);
+      }
+
+      try
+      {
+         if (pool != null)
+         {
+            log.debug("Stopping the session pool " + pool);
+            pool.stop();
+         }
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error clearing the pool " + pool, t);
+      }
+   }
+
+   /**
+    * Handles the setup
+    */
+   private class SetupActivation implements Work
+   {
+      public void run()
+      {
+         try
+         {
+            setup();
+         }
+         catch (Throwable t)
+         {
+            handleFailure(t);
+         }
+      }
+
+      public void release()
+      {
+      }
+   }
+}

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsActivationSpec.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsActivationSpec.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsActivationSpec.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,724 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow;
+
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.resource.ResourceException;
+import javax.resource.spi.ActivationSpec;
+import javax.resource.spi.InvalidPropertyException;
+import javax.resource.spi.ResourceAdapter;
+
+import org.jboss.logging.Logger;
+import org.jboss.util.Strings;
+
+/**
+ * A generic jms ActivationSpec.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 60926 $
+ */
+public class JmsActivationSpec implements ActivationSpec
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(JmsActivationSpec.class);
+
+   /** The resource adapter */
+   private ResourceAdapter ra;
+
+   /** The destination */
+   private String destination;
+
+   /** The destination type */
+   private boolean isTopic = false;
+
+   /** The message selector */
+   private String messageSelector;
+
+   /** The acknowledgement mode */
+   private int acknowledgeMode;
+
+   /** The subscription durability */
+   private boolean subscriptionDurability;
+
+   /** The client id */
+   private String clientId;
+
+   /** The subscription name */
+   private String subscriptionName;
+
+   /** The reconnect interval in seconds */
+   private long reconnectInterval = 10;
+
+   /** The jms provider adapter jndi name */
+   private String providerAdapterJNDI = "java:/DefaultJMSProvider";
+
+   /** The user */
+   private String user;
+
+   /** The password */
+   private String pass;
+
+   /** The maximum number of messages */
+   private int maxMessages = 1;
+
+   /** The minimum number of sessions */
+   private int minSession = 1;
+
+   /** The maximum number of sessions */
+   private int maxSession = 15;
+
+   /** The keep alive time for sessions */
+   private long keepAlive = 60000;
+
+   /** Is the session transacted */
+   private boolean sessionTransacted = true;
+
+   /** The DLQ handler class */
+   private String dLQHandler = "org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.dlq.GenericDLQHandler";
+
+   /** Whether to use a DLQ */
+   private boolean useDLQ = true;
+
+   /** The DLQ jndi binding */
+   private String dLQJNDIName = "queue/DLQ";
+
+   /** The DLQ user */
+   private String dLQUser;
+
+   /** The DLQ password */
+   private String dLQPassword;
+
+   /** The DLQ client id  */
+   private String dLQClientID;
+
+   /** The DLQ max resent  */
+   private int dLQMaxResent = 5;
+   
+   //Used to specify whether or not we should attempt to redeliver a message in an unspecified txn context
+   private boolean redeliverUnspecified = true;
+   
+   private int transactionTimeout;
+   
+   private Boolean isSameRMOverrideValue;
+   
+   private boolean forceClearOnShutdown = false;
+   
+   private long forceClearOnShutdownInterval = 1000;
+   
+   private int forceClearAttempts = 0;
+   
+   public void setForceClearOnShutdown(boolean forceClear)
+   {
+      this.forceClearOnShutdown = forceClear;
+   }   
+   
+   public boolean isForceClearOnShutdown()
+   {
+      return this.forceClearOnShutdown;
+   }
+   
+   public long getForceClearOnShutdownInterval()
+   {
+      return this.forceClearOnShutdownInterval;
+   }
+   
+   public void setForceClearOnShutdownInterval(long forceClearOnShutdownInterval)
+   {
+      this.forceClearOnShutdownInterval = forceClearOnShutdownInterval;
+   }
+   
+   public int getForceClearAttempts()
+   {
+      return forceClearAttempts;
+   }
+   
+   public void setForceClearAttempts(int forceClearAttempts)
+   {
+      this.forceClearAttempts = forceClearAttempts;
+   }
+   
+   /**
+    * @return the acknowledgeMode.
+    */
+   public String getAcknowledgeMode()
+   {
+      if (sessionTransacted)
+         return "TRANSACTED";
+      else if (Session.DUPS_OK_ACKNOWLEDGE == acknowledgeMode)
+         return "DUPS_OK_ACKNOWLEDGE";
+      else
+         return "AUTO_ACKNOWLEDGE";
+   }
+
+   /**
+    * @param acknowledgeMode The acknowledgeMode to set.
+    */
+   public void setAcknowledgeMode(String acknowledgeMode)
+   {
+      if ("DUPS_OK_ACKNOWLEDGE".equals(acknowledgeMode))
+         this.acknowledgeMode = Session.DUPS_OK_ACKNOWLEDGE;
+      else if ("AUTO_ACKNOWLEDGE".equals(acknowledgeMode))
+         this.acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
+      else if ("SESSION_TRANSACTED".equals(acknowledgeMode))
+         this.acknowledgeMode = Session.SESSION_TRANSACTED;
+      else
+         throw new IllegalArgumentException("Unsupported acknowledgement mode " + acknowledgeMode);
+   }
+
+   /**
+    * @return the acknowledgement mode
+    */
+   public int getAcknowledgeModeInt()
+   {
+      if (sessionTransacted)
+         return Session.SESSION_TRANSACTED;
+      return acknowledgeMode;
+   }
+
+   /**
+    * @return the clientId.
+    */
+   public String getClientId()
+   {
+      return clientId;
+   }
+
+   /**
+    * @param clientId The clientId to set.
+    */
+   public void setClientId(String clientId)
+   {
+      this.clientId = clientId;
+   }
+
+   /**
+    * @return the destination.
+    */
+   public String getDestination()
+   {
+      return destination;
+   }
+
+   /**
+    * @param destination The destination to set.
+    */
+   public void setDestination(String destination)
+   {
+      this.destination = destination;
+   }
+
+   /**
+    * @return the destinationType.
+    */
+   public String getDestinationType()
+   {
+      if (isTopic)
+         return Topic.class.getName();
+      else
+         return Queue.class.getName();
+   }
+
+   /**
+    * @param destinationType The destinationType to set.
+    */
+   public void setDestinationType(String destinationType)
+   {
+      if (Topic.class.getName().equals(destinationType))
+         this.isTopic = true;
+      else
+         this.isTopic = false;
+   }
+
+   /**
+    * @return whether this is for a topic.
+    */
+   public boolean isTopic()
+   {
+      return isTopic;
+   }
+
+   /**
+    * @return the messageSelector.
+    */
+   public String getMessageSelector()
+   {
+      return messageSelector;
+   }
+
+   /**
+    * @param messageSelector The messageSelector to set.
+    */
+   public void setMessageSelector(String messageSelector)
+   {
+      this.messageSelector = messageSelector;
+   }
+
+   /**
+    * @return the subscriptionDurability.
+    */
+   public String getSubscriptionDurability()
+   {
+      if (subscriptionDurability)
+         return "Durable";
+      else
+         return "NonDurable";
+   }
+
+   /**
+    * @param subscriptionDurability The subscriptionDurability to set.
+    */
+   public void setSubscriptionDurability(String subscriptionDurability)
+   {
+      this.subscriptionDurability = "Durable".equals(subscriptionDurability);
+   }
+
+   /**
+    * @return wether the subscription is durable.
+    */
+   public boolean isDurable()
+   {
+      return subscriptionDurability;
+   }
+
+   /**
+    * @return the subscriptionName.
+    */
+   public String getSubscriptionName()
+   {
+      return subscriptionName;
+   }
+
+   /**
+    * @param subscriptionName The subscriptionName to set.
+    */
+   public void setSubscriptionName(String subscriptionName)
+   {
+      this.subscriptionName = subscriptionName;
+   }
+
+   /**
+    * @return the reconnectInterval.
+    */
+   public long getReconnectInterval()
+   {
+      return reconnectInterval;
+   }
+
+   /**
+    * @param reconnectInterval The reconnectInterval to set.
+    */
+   public void setReconnectInterval(long reconnectInterval)
+   {
+      this.reconnectInterval = reconnectInterval;
+   }
+
+   /**
+    * @return the reconnect interval
+    */
+   public long getReconnectIntervalLong()
+   {
+      return reconnectInterval * 1000;
+   }
+
+   /**
+    * @return the providerAdapterJNDI.
+    */
+   public String getProviderAdapterJNDI()
+   {
+      return providerAdapterJNDI;
+   }
+
+   /**
+    * @param providerAdapterJNDI The providerAdapterJNDI to set.
+    */
+   public void setProviderAdapterJNDI(String providerAdapterJNDI)
+   {
+      this.providerAdapterJNDI = providerAdapterJNDI;
+   }
+
+   /**
+    * @return the user.
+    */
+   public String getUser()
+   {
+      return user;
+   }
+
+   /**
+    * @param user The user to set.
+    */
+   public void setUser(String user)
+   {
+      this.user = user;
+   }
+
+   /**
+    * @return the password.
+    */
+   public String getPassword()
+   {
+      return pass;
+   }
+
+   /**
+    * @param pass The password to set.
+    */
+   public void setPassword(String pass)
+   {
+      this.pass = pass;
+   }
+
+   /**
+    * @return the maxMessages.
+    */
+   public int getMaxMessages()
+   {
+      return maxMessages;
+   }
+
+   /**
+    * @param maxMessages The maxMessages to set.
+    */
+   public void setMaxMessages(int maxMessages)
+   {
+      this.maxSession = maxMessages;
+   }
+
+   /**
+    * @return the maximum number of messages
+    */
+   public int getMaxMessagesInt()
+   {
+      return maxMessages;
+   }
+
+   /**
+    * @return the minSession.
+    */
+   public int getMinSession()
+   {
+      return minSession;
+   }
+
+   /**
+    * @param minSession The minSession to set.
+    */
+   public void setMinSession(int minSession)
+   {
+      this.minSession = minSession;
+   }
+
+   /**
+    * @return the minimum number of sessions
+    */
+   public int getMinSessionInt()
+   {
+      return minSession;
+   }
+
+   /**
+    * @return the maxSession.
+    */
+   public int getMaxSession()
+   {
+      return maxSession;
+   }
+
+   /**
+    * @param maxSession The maxSession to set.
+    */
+   public void setMaxSession(int maxSession)
+   {
+      this.maxSession = maxSession;
+   }
+
+   /**
+    * @return the maximum number of sessions
+    */
+   public int getMaxSessionInt()
+   {
+      return maxSession;
+   }
+
+   /**
+    * @return the keepAlive.
+    */
+   public long getKeepAlive()
+   {
+      return keepAlive;
+   }
+
+   /**
+    * @param keepAlive The keepAlive to set.
+    */
+   public void setKeepAlive(long keepAlive)
+   {
+      this.keepAlive = keepAlive;
+   }
+
+   /**
+    * @return the keep alive time of the session
+    */
+   public long getKeepAliveLong()
+   {
+      return keepAlive;
+   }
+
+   /**
+    * @return the sessionTransacted.
+    */
+   public boolean getSessionTransacted()
+   {
+      return sessionTransacted;
+   }
+
+   /**
+    * @param sessionTransacted The sessionTransacted to set.
+    */
+   public void setSessionTransacted(boolean sessionTransacted)
+   {
+      this.sessionTransacted = sessionTransacted;
+   }
+
+   /**
+    * @return whether the session is transaction
+    */
+   public boolean isSessionTransacted()
+   {
+      return sessionTransacted;
+   }
+
+   /**
+    * @return Returns the dLQHandler.
+    */
+   public String getDLQHandler()
+   {
+      return dLQHandler;
+   }
+
+   /**
+    * @param handler The dLQHandler to set.
+    */
+   public void setDLQHandler(String handler)
+   {
+      this.dLQHandler = handler;
+   }
+
+   /**
+    * @return Returns the dLQJNDIName.
+    */
+   public String getDLQJNDIName()
+   {
+      return dLQJNDIName;
+   }
+
+   /**
+    * @param name The dLQJNDIName to set.
+    */
+   public void setDLQJNDIName(String name)
+   {
+      dLQJNDIName = name;
+   }
+
+   /**
+    * @return Returns the useDLQ.
+    */
+   public boolean getUseDLQ()
+   {
+      return useDLQ;
+   }
+
+   /**
+    * @param useDLQ The useDLQ to set.
+    */
+   public void setUseDLQ(boolean useDLQ)
+   {
+      this.useDLQ = useDLQ;
+   }
+
+   /**
+    * Whether we should use a DLQ
+    * 
+    * @return true when using a DLQ
+    */
+   public boolean isUseDLQ()
+   {
+      return useDLQ;
+   }
+
+   /**
+    * @return Returns the dLQClientID.
+    */
+   public String getDLQClientID()
+   {
+      return dLQClientID;
+   }
+
+   /**
+    * @param clientID The dLQClientID to set.
+    */
+   public void setDLQClientID(String clientID)
+   {
+      dLQClientID = clientID;
+   }
+
+   /**
+    * @return Returns the dLQPassword.
+    */
+   public String getDLQPassword()
+   {
+      return dLQPassword;
+   }
+
+   /**
+    * @param password The dLQPassword to set.
+    */
+   public void setDLQPassword(String password)
+   {
+      dLQPassword = password;
+   }
+
+   /**
+    * @return Returns the dLQUser.
+    */
+   public String getDLQUser()
+   {
+      return dLQUser;
+   }
+
+   /**
+    * @param user The dLQUser to set.
+    */
+   public void setDLQUser(String user)
+   {
+      dLQUser = user;
+   }
+
+   /**
+    * @return Returns the maxResent.
+    */
+   public int getDLQMaxResent()
+   {
+      return dLQMaxResent;
+   }
+   /**
+    * @param maxResent The maxResent to set.
+    */
+   public void setDLQMaxResent(int maxResent)
+   {
+      this.dLQMaxResent = maxResent;
+   }
+
+   public ResourceAdapter getResourceAdapter()
+   {
+      return ra;
+   }
+
+   public void setResourceAdapter(ResourceAdapter ra) throws ResourceException
+   {
+      this.ra = ra;
+   }
+
+   public void validate() throws InvalidPropertyException
+   {
+      if (log.isTraceEnabled())
+         log.trace("validate " + this);
+      // TODO validate
+   }
+
+   public String toString()
+   {
+      StringBuffer buffer = new StringBuffer();
+      buffer.append(Strings.defaultToString(this)).append('(');
+      buffer.append("ra=").append(ra);
+      buffer.append(" destination=").append(destination);
+      buffer.append(" isTopic=").append(isTopic);
+      if (messageSelector != null)
+         buffer.append(" selector=").append(messageSelector);
+      buffer.append(" tx=").append(sessionTransacted);
+      if (sessionTransacted == false)
+         buffer.append(" ack=").append(getAcknowledgeMode());
+      buffer.append(" durable=").append(subscriptionDurability);
+      if (clientId != null)
+         buffer.append(" clientID=").append(clientId);
+      if (subscriptionName != null)
+         buffer.append(" subscription=").append(subscriptionName);
+      buffer.append(" reconnect=").append(reconnectInterval);
+      buffer.append(" provider=").append(providerAdapterJNDI);
+      buffer.append(" user=").append(user);
+      if (pass != null)
+         buffer.append(" pass=").append("<not shown>");
+      buffer.append(" maxMessages=").append(maxMessages);
+      buffer.append(" minSession=").append(minSession);
+      buffer.append(" maxSession=").append(maxSession);
+      buffer.append(" keepAlive=").append(keepAlive);
+      buffer.append(" useDLQ=").append(useDLQ);
+      if (useDLQ)
+      {
+         buffer.append(" DLQHandler=").append(dLQHandler);
+         buffer.append(" DLQJndiName=").append(dLQJNDIName);
+         buffer.append(" DLQUser=").append(dLQUser);
+         if (dLQPassword != null)
+            buffer.append(" DLQPass=").append("<not shown>");
+         if (dLQClientID != null)
+            buffer.append(" DLQClientID=").append(dLQClientID);
+         buffer.append(" DLQMaxResent=").append(dLQMaxResent);
+      }
+      buffer.append(')');
+      return buffer.toString();
+   }
+
+   public boolean getRedeliverUnspecified()
+   {
+      return redeliverUnspecified;
+   }
+
+   public void setRedeliverUnspecified(boolean redeliverUnspecified)
+   {
+      this.redeliverUnspecified = redeliverUnspecified;
+   }
+
+   public int getTransactionTimeout()
+   {
+      return transactionTimeout;
+   }
+
+   public void setTransactionTimeout(int transactionTimeout)
+   {
+      this.transactionTimeout = transactionTimeout;
+   }
+   
+   public Boolean getIsSameRMOverrideValue()
+   {
+      return isSameRMOverrideValue;
+   }
+
+   public void setIsSameRMOverrideValue(Boolean isSameRMOverrideValue)
+   {
+      this.isSameRMOverrideValue = isSameRMOverrideValue;
+   }
+
+
+
+}
\ No newline at end of file

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsServerSession.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsServerSession.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsServerSession.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,526 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.ServerSession;
+import javax.jms.Session;
+import javax.jms.XAConnection;
+import javax.jms.XASession;
+import javax.resource.spi.endpoint.MessageEndpoint;
+import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.resource.spi.work.Work;
+import javax.resource.spi.work.WorkEvent;
+import javax.resource.spi.work.WorkException;
+import javax.resource.spi.work.WorkListener;
+import javax.resource.spi.work.WorkManager;
+import javax.transaction.Status;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.logging.Logger;
+import org.jboss.resource.connectionmanager.xa.JcaXAResourceWrapperFactory;
+
+/**
+ * A generic jms session pool.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="mailto:weston.price at jboss.com>Weston Price</a> 
+ * @version $Revision: 60926 $
+ */
+public class JmsServerSession implements ServerSession, MessageListener, Work, WorkListener
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(JmsServerSession.class);
+
+   /** The session pool */
+   JmsServerSessionPool pool;
+
+   /** The transacted flag */
+   boolean transacted;
+
+   /** The acknowledge mode */
+   int acknowledge;
+
+   /** The session */
+   Session session;
+
+   /** Any XA session */
+   XASession xaSession;
+
+   /** The endpoint */
+   MessageEndpoint endpoint;
+
+   /** Any DLQ handler */
+   DLQHandler dlqHandler;
+
+   TransactionDemarcationStrategy txnStrategy;
+
+   /**
+    * Create a new JmsServerSession
+    * 
+    * @param pool the server session pool
+    */
+   public JmsServerSession(JmsServerSessionPool pool)
+   {
+      this.pool = pool;
+
+   }
+
+   /**
+    * Setup the session
+    */
+   public void setup() throws Exception
+   {
+      JmsActivation activation = pool.getActivation();
+      JmsActivationSpec spec = activation.getActivationSpec();
+
+      dlqHandler = activation.getDLQHandler();
+
+      Connection connection = activation.getConnection();
+
+      // Create the session
+      if (connection instanceof XAConnection && activation.isDeliveryTransacted())
+      {
+         xaSession = ((XAConnection) connection).createXASession();
+         session = xaSession.getSession();
+      }
+      else
+      {
+         transacted = spec.isSessionTransacted();
+         acknowledge = spec.getAcknowledgeModeInt();
+         session = connection.createSession(transacted, acknowledge);
+      }
+
+      // Get the endpoint
+      MessageEndpointFactory endpointFactory = activation.getMessageEndpointFactory();
+      XAResource xaResource = null;
+
+      if (activation.isDeliveryTransacted() && xaSession != null)
+         xaResource = xaSession.getXAResource();
+
+      endpoint = endpointFactory.createEndpoint(xaResource);
+
+      // Set the message listener
+      session.setMessageListener(this);
+   }
+
+   /**
+    * Stop the session
+    */
+   public void teardown()
+   {
+      try
+      {
+         if (endpoint != null)
+            endpoint.release();
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error releasing endpoint " + endpoint, t);
+      }
+
+      try
+      {
+         if (xaSession != null)
+            xaSession.close();
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error releasing xaSession " + xaSession, t);
+      }
+
+      try
+      {
+         if (session != null)
+            session.close();
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error releasing session " + session, t);
+      }
+   }
+
+   public void onMessage(Message message)
+   {
+      try
+      {
+         endpoint.beforeDelivery(JmsActivation.ONMESSAGE);
+
+         try
+         {
+            if (dlqHandler == null || dlqHandler.handleRedeliveredMessage(message) == false)
+            {
+               MessageListener listener = (MessageListener) endpoint;
+               listener.onMessage(message);
+            }
+         }
+         finally
+         {
+            endpoint.afterDelivery();
+
+            if (dlqHandler != null)
+               dlqHandler.messageDelivered(message);
+         }
+      }
+
+      catch (Throwable t)
+      {
+         log.error("Unexpected error delivering message " + message, t);
+
+         if (txnStrategy != null)
+            txnStrategy.error();
+
+      }
+
+   }
+
+   public Session getSession() throws JMSException
+   {
+      return session;
+   }
+
+   public void start() throws JMSException
+   {
+      JmsActivation activation = pool.getActivation();
+      WorkManager workManager = activation.getWorkManager();
+      try
+      {
+         workManager.scheduleWork(this, 0, null, this);
+      }
+      catch (WorkException e)
+      {
+         log.error("Unable to schedule work", e);
+         throw new JMSException("Unable to schedule work: " + e.toString());
+      }
+   }
+
+   public void run()
+   {
+
+      try
+      {
+         txnStrategy = createTransactionDemarcation();
+
+      }
+      catch (Throwable t)
+      {
+         log.error("Error creating transaction demarcation. Cannot continue.");
+         return;
+      }
+
+      try
+      {
+         session.run();
+      }
+      catch (Throwable t)
+      {
+         if (txnStrategy != null)
+            txnStrategy.error();
+
+      }
+      finally
+      {
+         if (txnStrategy != null)
+            txnStrategy.end();
+
+         txnStrategy = null;
+      }
+
+   }
+
+   private TransactionDemarcationStrategy createTransactionDemarcation()
+   {
+      return new DemarcationStrategyFactory().getStrategy();
+
+   }
+
+   public void release()
+   {
+   }
+
+   public void workAccepted(WorkEvent e)
+   {
+   }
+
+   public void workCompleted(WorkEvent e)
+   {
+      // don't recycle session
+      // pool.returnServerSession(this);
+   }
+
+   public void workRejected(WorkEvent e)
+   {
+      // don't recycle session
+      // pool.returnServerSession(this);
+   }
+
+   public void workStarted(WorkEvent e)
+   {
+   }
+
+   private class DemarcationStrategyFactory
+   {
+
+      TransactionDemarcationStrategy getStrategy()
+      {
+         TransactionDemarcationStrategy current = null;
+         final JmsActivationSpec spec = pool.getActivation().getActivationSpec();
+         final JmsActivation activation = pool.getActivation();
+
+         if (activation.isDeliveryTransacted() && xaSession != null)
+         {
+            try
+            {
+               current = new XATransactionDemarcationStrategy();
+            }
+            catch (Throwable t)
+            {
+               log.error(this + " error creating transaction demarcation ", t);
+            }
+
+         }
+         else
+         {
+
+            return new LocalDemarcationStrategy();
+
+         }
+
+         return current;
+      }
+
+   }
+
+   private interface TransactionDemarcationStrategy
+   {
+      void error();
+
+      void end();
+
+   }
+
+   private class LocalDemarcationStrategy implements TransactionDemarcationStrategy
+   {
+      public void end()
+      {
+         final JmsActivationSpec spec = pool.getActivation().getActivationSpec();
+
+         if (spec.isSessionTransacted())
+         {
+            if (session != null)
+            {
+               try
+               {
+                  session.commit();
+               }
+               catch (JMSException e)
+               {
+                  log.error("Failed to commit session transaction", e);
+               }
+            }
+         }
+      }
+
+      public void error()
+      {
+         final JmsActivationSpec spec = pool.getActivation().getActivationSpec();
+
+         if (spec.isSessionTransacted())
+         {
+            if (session != null)
+
+               try
+               {
+                  /*
+                   * Looks strange, but this basically means
+                   * 
+                   * If the underlying connection was non-XA and the transaction attribute is REQUIRED
+                   * we rollback. Also, if the underlying connection was non-XA and the transaction
+                   * attribute is NOT_SUPPORT and the non standard redelivery behavior is enabled 
+                   * we rollback to force redelivery.
+                   * 
+                   */
+                  if (pool.getActivation().isDeliveryTransacted() || spec.getRedeliverUnspecified())
+                  {
+                     session.rollback();
+                  }
+
+               }
+               catch (JMSException e)
+               {
+                  log.error("Failed to rollback session transaction", e);
+               }
+
+         }
+      }
+
+   }
+
+   private class XATransactionDemarcationStrategy implements TransactionDemarcationStrategy
+   {
+
+      boolean trace = log.isTraceEnabled();
+
+      Transaction trans = null;
+
+      TransactionManager tm = pool.getActivation().getTransactionManager();;
+
+      public XATransactionDemarcationStrategy() throws Throwable
+      {
+
+         final int timeout = pool.getActivation().getActivationSpec().getTransactionTimeout();
+
+         if (timeout > 0)
+         {
+            log.trace("Setting transactionTimeout for JMSSessionPool to " + timeout);
+            tm.setTransactionTimeout(timeout);
+
+         }
+
+         tm.begin();
+
+         try
+         {
+            trans = tm.getTransaction();
+
+            if (trace)
+               log.trace(JmsServerSession.this + " using tx=" + trans);
+
+            if (xaSession != null)
+            {
+               XAResource res = JcaXAResourceWrapperFactory.getResourceWrapper(xaSession.getXAResource(), pool.getActivation().getActivationSpec().getIsSameRMOverrideValue());
+                  
+               if (!trans.enlistResource(res))
+               {
+                  throw new JMSException("could not enlist resource");
+               }
+               if (trace)
+                  log.trace(JmsServerSession.this + " XAResource '" + res + "' enlisted.");
+            }
+         }
+         catch (Throwable t)
+         {
+            try
+            {
+               tm.rollback();
+            }
+            catch (Throwable ignored)
+            {
+               log.trace(JmsServerSession.this + " ignored error rolling back after failed enlist", ignored);
+            }
+            throw t;
+         }
+
+      }
+
+      public void error()
+      {
+         // Mark for tollback TX via TM
+         try
+         {
+
+            if (trace)
+            {
+               log.trace(JmsServerSession.this + " using TM to mark TX for rollback tx=" + trans);
+               
+            }
+
+            trans.setRollbackOnly();
+         }
+         catch (Throwable t)
+         {
+            log.error(JmsServerSession.this + " failed to set rollback only", t);
+         }
+
+      }
+
+      public void end()
+      {
+         try
+         {
+
+            // Use the TM to commit the Tx (assert the correct association) 
+            Transaction currentTx = tm.getTransaction();
+            if (trans.equals(currentTx) == false)
+               throw new IllegalStateException("Wrong tx association: expected " + trans + " was " + currentTx);
+
+            // Marked rollback
+            if (trans.getStatus() == Status.STATUS_MARKED_ROLLBACK)
+            {
+               if (trace)
+                  log.trace(JmsServerSession.this + " rolling back JMS transaction tx=" + trans);
+               // actually roll it back
+               tm.rollback();
+
+               // NO XASession? then manually rollback.
+               // This is not so good but
+               // it's the best we can do if we have no XASession.
+               if (xaSession == null && pool.getActivation().isDeliveryTransacted())
+               {
+                  session.rollback();
+               }
+            }
+
+            else if (trans.getStatus() == Status.STATUS_ACTIVE)
+            {
+               // Commit tx
+               // This will happen if
+               // a) everything goes well
+               // b) app. exception was thrown
+               if (trace)
+                  log.trace(JmsServerSession.this + " commiting the JMS transaction tx=" + trans);
+               tm.commit();
+
+               // NO XASession? then manually commit.  This is not so good but
+               // it's the best we can do if we have no XASession.
+               if (xaSession == null && pool.getActivation().isDeliveryTransacted())
+               {
+                  session.commit();
+               }
+
+            }
+            else
+            {
+               tm.suspend();
+
+               if (xaSession == null && pool.getActivation().isDeliveryTransacted())
+               {
+                  session.rollback();
+               }
+
+            }
+
+         }
+         catch (Throwable t)
+         {
+            log.error(JmsServerSession.this + " failed to commit/rollback", t);
+         }
+
+      }
+
+   }
+}
\ No newline at end of file

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsServerSessionPool.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsServerSessionPool.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/JmsServerSessionPool.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,312 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionConsumer;
+import javax.jms.JMSException;
+import javax.jms.Queue;
+import javax.jms.ServerSession;
+import javax.jms.ServerSessionPool;
+import javax.jms.Topic;
+
+import org.jboss.logging.Logger;
+
+/**
+ * A generic jms session pool.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 60552 $
+ */
+public class JmsServerSessionPool implements ServerSessionPool
+{
+   /** The logger */
+   private static final Logger log = Logger.getLogger(JmsServerSessionPool.class);
+      
+   /** The activation */
+   JmsActivation activation;
+
+   /** The consumer */
+   ConnectionConsumer consumer;
+
+   /** The server sessions */
+   ArrayList serverSessions = new ArrayList();
+   
+   /** Whether the pool is stopped */
+   boolean stopped = false;
+   
+   /** The number of sessions */
+   int sessionCount = 0;
+   
+   
+   /**
+    * Create a new session pool
+    * 
+    * @param activation the jms activation
+    */
+   public JmsServerSessionPool(JmsActivation activation)
+   {
+      this.activation = activation;
+   }
+
+   /**
+    * @return the activation
+    */
+   public JmsActivation getActivation()
+   {
+      return activation;
+   }
+   
+   /**
+    * Start the server session pool
+    * 
+    * @throws Exeption for any error
+    */
+   public void start() throws Exception
+   {
+      setupSessions();
+      setupConsumer();
+   }
+
+   /**
+    * Stop the server session pool
+    */
+   public void stop()
+   {
+      teardownConsumer();
+      teardownSessions();
+   }
+   
+   public ServerSession getServerSession() throws JMSException
+   {
+      boolean trace = log.isTraceEnabled();
+      if (trace)
+         log.trace("getServerSession");
+      
+      ServerSession result = null;
+      
+      try
+      {
+         synchronized (serverSessions)
+         {
+            while (true)
+            {
+               int sessionsSize = serverSessions.size();
+               
+               if (stopped)
+                  throw new Exception("Cannot get a server session after the pool is stopped");
+               
+               else if (sessionsSize > 0)
+               {
+                  result = (ServerSession) serverSessions.remove(sessionsSize-1);
+                  break;
+               }
+               
+               else
+               {
+                  try
+                  {
+                     serverSessions.wait();
+                  }
+                  catch (InterruptedException ignored)
+                  {
+                  }
+               }
+            }
+         }
+      }
+      catch (Throwable t)
+      {
+         log.error("Unable to get a server session", t);
+         throw new JMSException("Unable to get a server session " + t);
+      }
+      
+      if (trace)
+         log.trace("Returning server session " + result);
+      
+      return result;
+   }
+
+   /**
+    * Return the server session
+    * 
+    * @param session the session
+    */
+   protected void returnServerSession(JmsServerSession session)
+   {     
+      synchronized (serverSessions)
+      {
+         if (stopped)
+         {
+            session.teardown();
+            --sessionCount;
+         }
+         else
+            serverSessions.add(session);
+         serverSessions.notifyAll();
+      }
+   }
+   
+   /**
+    * Setup the sessions
+    * 
+    * @throws Exeption for any error
+    */
+   protected void setupSessions() throws Exception
+   {    
+      JmsActivationSpec spec = activation.getActivationSpec();
+      ArrayList clonedSessions = null;
+
+      // Create the sessions
+      synchronized (serverSessions)
+      {
+         for (int i = 0; i < spec.getMaxSessionInt(); ++i)
+         {
+            JmsServerSession session = new JmsServerSession(this);
+            serverSessions.add(session);
+         }
+         sessionCount = serverSessions.size();
+         clonedSessions = (ArrayList) serverSessions.clone();
+
+      }
+      
+      // Start the sessions
+      for (int i = 0; i < clonedSessions.size(); ++ i)
+      {
+         JmsServerSession session = (JmsServerSession) clonedSessions.get(i);
+         session.setup();
+      }
+   }
+
+   /**
+    * Stop the sessions
+    */
+   protected void teardownSessions()
+   { 
+      synchronized (serverSessions)
+      {
+         // Disallow any new sessions
+         stopped = true;
+         serverSessions.notifyAll();
+         
+         // Stop inactive sessions
+         for (int i = 0; i < serverSessions.size(); ++i)
+         {
+            JmsServerSession session = (JmsServerSession) serverSessions.get(i);
+            session.teardown();
+         }
+
+         sessionCount -= serverSessions.size();
+         serverSessions.clear();
+         
+         if (activation.getActivationSpec().isForceClearOnShutdown())
+         {        
+            int attempts = 0;
+            int forceClearAttempts = activation.getActivationSpec().getForceClearAttempts();
+            long forceClearInterval = activation.getActivationSpec().getForceClearOnShutdownInterval();
+            
+            log.trace("Force clear behavior in effect. Waiting for " + forceClearInterval + " milliseconds for " + forceClearAttempts + " attempts.");
+           
+            while((sessionCount > 0) && (attempts < forceClearAttempts))
+            {
+               try
+               {
+                  serverSessions.wait(forceClearInterval);
+                  log.trace("Clear attempt " + attempts); 
+                  ++attempts;               
+            
+               }catch(InterruptedException ignore)
+               {
+                  
+               }
+            
+            }
+         }
+         else
+         {
+            // Wait for inuse sessions
+            while (sessionCount > 0)
+            {
+               try
+               {
+                  serverSessions.wait();
+               }
+               catch (InterruptedException ignore)
+               {
+               }
+            }
+         }
+      }
+   }
+   
+   /**
+    * Setup the connection consumer
+    * 
+    * @throws Exeption for any error
+    */
+   protected void setupConsumer() throws Exception
+   {
+      Connection connection = activation.getConnection();
+      JmsActivationSpec spec = activation.getActivationSpec();
+      String selector = spec.getMessageSelector();
+      int maxMessages = spec.getMaxMessagesInt();
+      if (spec.isTopic())
+      {
+         Topic topic = (Topic) activation.getDestination();
+         String subscriptionName = spec.getSubscriptionName();
+         if (spec.isDurable())
+            consumer = connection.createDurableConnectionConsumer(topic, subscriptionName, selector, this, maxMessages);
+         else
+            consumer = connection.createConnectionConsumer(topic, selector, this, maxMessages);
+      }
+      else
+      {
+         Queue queue = (Queue) activation.getDestination();
+         consumer = connection.createConnectionConsumer(queue, selector, this, maxMessages);
+      }
+      log.debug("Created consumer " + consumer);
+   }
+
+   /**
+    * Stop the connection consumer
+    */
+   protected void teardownConsumer()
+   {
+      try
+      {
+         if (consumer != null)
+         {
+            log.debug("Closing the " + consumer);
+            consumer.close();
+         }
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error closing the consumer " + consumer, t);
+      }
+   }
+
+}
\ No newline at end of file

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/AbstractDLQHandler.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/AbstractDLQHandler.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/AbstractDLQHandler.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,360 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.dlq;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueSender;
+import javax.jms.QueueSession;
+import javax.jms.TopicConnectionFactory;
+import javax.naming.Context;
+
+import org.jboss.jms.jndi.JMSProviderAdapter;
+import org.jboss.logging.Logger;
+import org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.DLQHandler;
+import org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.JmsActivation;
+import org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.JmsActivationSpec;
+import org.jboss.util.naming.Util;
+
+/**
+ * An abstract DLQ handler.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public abstract class AbstractDLQHandler implements DLQHandler, ExceptionListener
+{
+   /** The logger */
+   protected static final Logger log = Logger.getLogger(AbstractDLQHandler.class);
+
+   /** The activation */
+   protected JmsActivation activation;
+   
+   /** The DLQ */
+   protected Queue dlq;
+   
+   /** The DLQ Connection*/
+   protected QueueConnection connection;
+
+   public boolean handleRedeliveredMessage(Message msg)
+   {
+      boolean handled = handleDelivery(msg);
+      if (handled)
+         sendToDLQ(msg);
+      return handled;
+   }
+
+   public void messageDelivered(Message msg)
+   {
+   }
+   
+   public void setup(JmsActivation activation, Context ctx) throws Exception
+   {
+      this.activation = activation;
+      setupDLQDestination(ctx);
+      setupDLQConnection(ctx);
+   }
+
+   public void teardown()
+   {
+      teardownDLQConnection();
+      teardownDLQDestination();
+   }
+
+   public void onException(JMSException exception)
+   {
+      activation.handleFailure(exception);
+   }
+
+   /**
+    * Setup the DLQ Destination
+    * 
+    * @param ctx the naming context
+    * @throws Exception for any error
+    */
+   protected void setupDLQDestination(Context ctx) throws Exception
+   {
+      String name = activation.getActivationSpec().getDLQJNDIName();
+      dlq = (Queue) Util.lookup(ctx, name, Queue.class);
+   }
+
+   /**
+    * Teardown the DLQ Destination
+    */
+   protected void teardownDLQDestination()
+   {
+   }
+
+   /**
+    * Setup the DLQ Connection
+    * 
+    * @param ctx the naming context
+    * @throws Exception for any error
+    */
+   protected void setupDLQConnection(Context ctx) throws Exception
+   {
+      JmsActivationSpec spec = activation.getActivationSpec();
+      String user = spec.getDLQUser();
+      String pass = spec.getDLQPassword();
+      String clientID = spec.getDLQClientID();
+      JMSProviderAdapter adapter = activation.getProviderAdapter();
+      String queueFactoryRef = adapter.getQueueFactoryRef();
+      log.debug("Attempting to lookup dlq connection factory " + queueFactoryRef);
+      QueueConnectionFactory qcf = (QueueConnectionFactory) Util.lookup(ctx, queueFactoryRef, QueueConnectionFactory.class);
+      log.debug("Got dlq connection factory " + qcf + " from " + queueFactoryRef);
+      log.debug("Attempting to create queue connection with user " + user);
+      if (user != null)
+         connection = qcf.createQueueConnection(user, pass);
+      else
+         connection = qcf.createQueueConnection();
+      if (clientID != null)
+         connection.setClientID(clientID);
+      connection.setExceptionListener(this);
+      log.debug("Using queue connection " + connection);
+   }
+
+   /**
+    * Teardown the DLQ Connection
+    */
+   protected void teardownDLQConnection()
+   {
+      try
+      {
+         if (connection != null)
+         {
+            log.debug("Closing the " + connection);
+            connection.close();
+         }
+      }
+      catch (Throwable t)
+      {
+         log.debug("Error closing the connection " + connection, t);
+      }
+   }
+   
+   /**
+    * Do we handle the message?
+    * 
+    * @param msg the message to handle
+    * @return true when we handle it
+    */
+   protected abstract boolean handleDelivery(Message msg);
+   
+   /**
+    * Warn that a message is being handled by the DLQ
+    *
+    * @param msg
+    * @param count the number of redelivers
+    * @param max the maximum number of redeliveries
+    */
+   protected void warnDLQ(Message msg, int count, int max)
+   {
+      log.warn("Message redelivered=" + count + " max=" + max + " sending it to the dlq " + msg);
+   }
+   
+   /**
+    * Send the message to the dlq
+    * 
+    * @param msg message to send
+    */
+   protected void sendToDLQ(Message msg)
+   {
+      int deliveryMode = getDeliveryMode(msg);
+      int priority = getPriority(msg);
+      long timeToLive = getTimeToLive(msg);
+      
+      // If we get a negative time to live that means the message has expired
+      if (timeToLive < 0)
+      {
+         if (log.isTraceEnabled())
+            log.trace("Not sending the message to the DLQ, it has expired " + msg);
+         return;
+      }
+      
+      Message copy = makeWritable(msg);
+      if (copy != null)
+         doSend(copy, deliveryMode, priority, timeToLive);
+   }
+   
+   /**
+    * Get the delivery mode for the DLQ message
+    *
+    * @param msg the message
+    * @return the delivery mode
+    */
+   protected int getDeliveryMode(Message msg)
+   {
+      try
+      {
+         return msg.getJMSDeliveryMode();
+      }
+      catch (Throwable t)
+      {
+         return Message.DEFAULT_DELIVERY_MODE;
+      }
+   }
+   
+   /**
+    * Get the priority for the DLQ message
+    *
+    * @param msg the message
+    * @return the priority
+    */
+   protected int getPriority(Message msg)
+   {
+      try
+      {
+         return msg.getJMSPriority();
+      }
+      catch (Throwable t)
+      {
+         return Message.DEFAULT_PRIORITY;
+      }
+   }
+   
+   /**
+    * Get the time to live for the DLQ message
+    *
+    * @param msg the message
+    * @return the time to live
+    */
+   protected long getTimeToLive(Message msg)
+   {
+      try
+      {
+         long expires = msg.getJMSExpiration();
+         if (expires == Message.DEFAULT_TIME_TO_LIVE)
+            return Message.DEFAULT_TIME_TO_LIVE;
+         return expires - System.currentTimeMillis();
+      }
+      catch (Throwable t)
+      {
+         return Message.DEFAULT_TIME_TO_LIVE;
+      }
+   }
+   
+   /**
+    * Make a writable copy of the message
+    *
+    * @param msg the message
+    * @return the copied message
+    */
+   protected Message makeWritable(Message msg)
+   {
+      boolean trace = log.isTraceEnabled();
+      
+      try
+      {
+         HashMap tmp = new HashMap();
+
+         // Save properties
+         for (Enumeration en = msg.getPropertyNames(); en.hasMoreElements();)
+         {
+            String key = (String) en.nextElement();
+            tmp.put(key, msg.getObjectProperty(key));
+         }
+         
+         // Make them writable
+         msg.clearProperties();
+
+         for (Iterator i = tmp.keySet().iterator(); i.hasNext();)
+         {
+            String key = (String) i.next();
+            try
+            {
+               msg.setObjectProperty(key, tmp.get(key));
+            }
+            catch (JMSException ignored)
+            {
+               if (trace)
+                  log.trace("Could not copy message property " + key, ignored);
+            }
+         }
+
+         msg.setStringProperty(JBOSS_ORIG_MESSAGEID, msg.getJMSMessageID());
+         Destination destination = msg.getJMSDestination();
+         if (destination != null)
+            msg.setStringProperty(JBOSS_ORIG_DESTINATION, destination.toString());
+
+         return msg;
+      }
+      catch (Throwable t)
+      {
+         log.error("Unable to make writable " + msg, t);
+         return null;
+      }
+   }
+   
+   /** 
+    * Do the message send
+    *
+    * @param msg the message
+    */
+   protected void doSend(Message msg, int deliveryMode, int priority, long timeToLive)
+   {
+      QueueSession session = null;
+      try
+      {
+         session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
+         QueueSender sender = session.createSender(dlq);
+         sender.send(msg, deliveryMode, priority, timeToLive);
+      }
+      catch (Throwable t)
+      {
+         handleSendError(msg, t);
+      }
+      finally
+      {
+         if (session != null)
+         {
+            try
+            {
+               session.close();
+            }
+            catch (Throwable t)
+            {
+               log.trace("Ignored ", t);
+            }
+         }
+      }
+   }
+   
+   /**
+    * Handle a failure to send the message to the dlq
+    *
+    * @param msg the message
+    * @param t the error
+    */
+   protected void handleSendError(Message msg, Throwable t)
+   {
+      log.error("DLQ " + dlq + " error sending message " + msg, t);
+   }
+}
\ No newline at end of file

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/GenericDLQHandler.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/GenericDLQHandler.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/GenericDLQHandler.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,145 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.dlq;
+
+import java.util.HashMap;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+
+/**
+ * A Generic DLQ Handler
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class GenericDLQHandler extends JBossMQDLQHandler
+{
+   /** Resent messages Map<MessageID, Integer> */
+   protected HashMap resent = new HashMap();
+
+   public void messageDelivered(Message msg)
+   {
+      try
+      {
+         String id = msg.getJMSMessageID();
+         if (id == null)
+         {
+            log.error("Message id is null? " + msg);
+            return;
+         }
+
+         clearResentCounter(id);
+      }
+      catch (Throwable t)
+      {
+         log.warn("Unexpected error processing delivery notification " + msg, t);
+      }
+   }
+
+   protected boolean handleDelivery(Message msg)
+   {
+      // Check for JBossMQ specific
+      boolean handled = super.handleDelivery(msg);
+      if (handled)
+         return true;
+      
+      try
+      {
+         if (msg.propertyExists(JMS_JBOSS_REDELIVERY_COUNT))
+            return false;
+
+         String id = msg.getJMSMessageID();
+         if (id == null)
+         {
+            log.error("Message id is null? " + msg);
+            return false;
+         }
+
+         int count = 0;
+         
+         try
+         {
+            if (msg.propertyExists(PROPERTY_DELIVERY_COUNT))
+               count = msg.getIntProperty(PROPERTY_DELIVERY_COUNT) - 1;
+         }
+         catch (JMSException ignored)
+         {
+            count = incrementResentCounter(id);
+         }
+         
+         if (count > maxResent)
+         {
+            warnDLQ(msg, count, maxResent);
+            clearResentCounter(id);
+            return true;
+         }
+      }
+      catch (Throwable t)
+      {
+         log.warn("Unexpected error checking whether dlq should be used " + msg, t);
+      }
+      
+      return false;
+   }
+   
+   /**
+    * Increment the resent counter for the message id
+    * 
+    * @param id the message id of the message
+    */
+   protected int incrementResentCounter(String id)
+   {
+      ResentInfo info;
+      synchronized (resent)
+      {
+         info = (ResentInfo) resent.get(id);
+         if (info == null)
+         {
+            info = new ResentInfo();
+            resent.put(id, info);
+         }
+      }
+      return ++info.count;
+   }
+   
+   /**
+    * Remove the resent counter for the message id
+    * 
+    * @param id the message id of the message
+    */
+   protected void clearResentCounter(String id)
+   {
+      synchronized (resent)
+      {
+         resent.remove(id);
+      }
+   }
+   
+   /**
+    * Resent Info
+    */
+   protected static class ResentInfo
+   {
+      int count = 0;
+   }
+}
\ No newline at end of file

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/JBossMQDLQHandler.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/JBossMQDLQHandler.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/inflow/dlq/JBossMQDLQHandler.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,77 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.dlq;
+
+import javax.jms.Message;
+import javax.naming.Context;
+
+import org.jboss.ejb3.test.mdbsessionpoolclear.adapter.jms.inflow.JmsActivation;
+
+/**
+ * A DLQ Handler that knows about JBossMQ redelivery properties
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 57189 $
+ */
+public class JBossMQDLQHandler extends AbstractDLQHandler
+{
+   /** Properties copied from org.jboss.mq.SpyMessage */
+   protected static final String JMS_JBOSS_REDELIVERY_COUNT = "JMS_JBOSS_REDELIVERY_COUNT";
+
+   /** Properties copied from org.jboss.mq.SpyMessage */
+   protected static final String JMS_JBOSS_REDELIVERY_LIMIT = "JMS_JBOSS_REDELIVERY_LIMIT";
+   
+   /** The maximum number of resends */
+   protected int maxResent;
+
+   public void setup(JmsActivation activation, Context ctx) throws Exception
+   {
+      super.setup(activation, ctx);
+      maxResent = activation.getActivationSpec().getDLQMaxResent();
+   }
+   
+   protected boolean handleDelivery(Message msg)
+   {
+      int max = maxResent;
+      try
+      {
+         if (msg.propertyExists(JMS_JBOSS_REDELIVERY_LIMIT))
+            max = msg.getIntProperty(JMS_JBOSS_REDELIVERY_LIMIT);
+
+         if (msg.propertyExists(JMS_JBOSS_REDELIVERY_COUNT))
+         {
+            int count = msg.getIntProperty(JMS_JBOSS_REDELIVERY_COUNT);
+         
+            if (count > max)
+            {
+               warnDLQ(msg, count, max);
+               return true;
+            }
+         }
+      }
+      catch (Throwable t)
+      {
+         log.warn("Unexpected error retrieving message properties " + msg, t);
+      }
+      return false;
+   }
+}
\ No newline at end of file

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/package.html
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/package.html	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/adapter/jms/package.html	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <!-- $Id: package.html 38347 2005-11-22 00:14:22Z adrian $ -->
+    <!--
+ JBoss, Home of Professional Open Source
+ Copyright 2005, JBoss Inc., and individual contributors as indicated
+ by the @authors tag. See the copyright.txt in the distribution for a
+ full listing of individual contributors.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+    -->
+  </head>
+
+  <body bgcolor="white">
+    <p>JMS Resource Adapter
+
+    <h2>Package Specification</h2>
+    <ul>
+      <li><a href="javascript: alert('not available')">Not Available</a>
+    </ul>
+      
+    <h2>Related Documentation</h2>
+    <ul>
+      <li><a href="javascript: alert('not available')">Not Available</a>
+    </ul>
+
+    <h2>Package Status</h2>
+    <ul>
+      <li><font color="green"><b>STABLE</b></font>
+    </ul>
+
+    <h2>Todo</h2>
+    <ul>
+      <li>???
+    </ul>
+
+    <!-- Put @see and @since tags down here. -->
+
+  </body>
+</html>

Added: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/unit/MDBUnitTestCase.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/unit/MDBUnitTestCase.java	                        (rev 0)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/ejb3/src/test/org/jboss/ejb3/test/mdbsessionpoolclear/unit/MDBUnitTestCase.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -0,0 +1,221 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.test.mdbsessionpoolclear.unit;
+
+import java.util.Date;
+import java.util.Set;
+
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueSender;
+import javax.jms.QueueSession;
+import javax.jms.TextMessage;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import junit.framework.Test;
+
+import org.jboss.ejb3.InitialContextFactory;
+import org.jboss.ejb3.test.mdbsessionpoolclear.TestStatus;
+import org.jboss.logging.Logger;
+import org.jboss.test.JBossTestCase;
+
+/**
+ * Sample client for the jboss container.
+ * 
+ * @author <a href="mailto:bill at burkecentral.com">Bill Burke</a>
+ * @version $Id: MDBUnitTestCase.java 63518 2007-06-13 22:32:28Z wolfc $
+ */
+public class MDBUnitTestCase extends JBossTestCase
+{
+   private static final Logger log = Logger.getLogger(MDBUnitTestCase.class);
+
+   public MDBUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+  
+   public void testEjb21Mdb() throws Exception
+   {
+      TestStatus status = (TestStatus) getInitialContext().lookup(
+            "TestStatusBean/remote");
+      status.clear();
+      
+      QueueConnection cnn = null;
+      QueueSender sender = null;
+      QueueSession session = null;
+
+      Queue queue = (Queue) getInitialContext().lookup("queue/mdbsessionpoolclearQueue");
+      QueueConnectionFactory factory = getQueueConnectionFactory();
+      cnn = factory.createQueueConnection();
+      session = cnn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
+
+      TextMessage msg = session.createTextMessage("Hello World " + new Date());
+
+      sender = session.createSender(queue);
+      System.out.println(new Date() + "*** Sending 1" );
+      sender.send(msg);
+      session.close();
+      cnn.close();
+      
+      Thread.sleep(2000);
+      
+      MBeanServerConnection server = getServer();
+      ObjectName destinationManager = new ObjectName("jboss.mq:service=DestinationManager");
+      Object[] params = {};
+      String[] sig = {};
+      System.out.println(new Date() + "*** Stopping DestinationManager");
+      Object success = server.invoke(destinationManager, "stop", params, sig);
+      
+      ObjectName jmsContainerInvokerQuery = new ObjectName("jboss.j2ee:binding=my-message-driven-bean,*");
+      Set mbeans = server.queryMBeans(jmsContainerInvokerQuery, null);
+      assertEquals(1, mbeans.size());
+      ObjectInstance jmsContainerInvokerInstance = (ObjectInstance)mbeans.iterator().next();
+      ObjectName jmsContainerInvoker = jmsContainerInvokerInstance.getObjectName();
+      int numActiveSessions = (Integer)server.getAttribute(jmsContainerInvoker, "NumActiveSessions");
+      assertEquals(1, numActiveSessions);
+      boolean forceClear = (Boolean)server.getAttribute(jmsContainerInvoker, "ForceClearOnShutdown");
+      assertTrue(forceClear);
+      int forceClearAttempts = (Integer)server.getAttribute(jmsContainerInvoker, "ForceClearAttempts");
+      assertEquals(5, forceClearAttempts);
+      long forceClearOnShutdownInterval = (Long)server.getAttribute(jmsContainerInvoker, "ForceClearOnShutdownInterval");
+      assertEquals(500, forceClearOnShutdownInterval);
+      
+      Thread.sleep(2000);
+      
+      System.out.println(new Date() + "*** Starting DestinationManager");
+      success = server.invoke(destinationManager, "start", params, sig);
+
+      Thread.sleep(60 * 1000);
+      
+      numActiveSessions = (Integer)server.getAttribute(jmsContainerInvoker, "NumActiveSessions");
+      assertEquals(1, numActiveSessions);
+      
+      assertEquals(1, status.queueFired());
+      
+      cnn = factory.createQueueConnection();
+      session = cnn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
+
+      msg = session.createTextMessage("Hello World " + new Date());
+
+      sender = session.createSender(queue);
+      
+      sender.send(msg);
+      System.out.println(new Date() + "*** Sending 2");
+      session.close();
+      cnn.close();
+      
+      Thread.sleep(10 * 1000);
+      
+      assertEquals(2, status.queueFired());
+   }
+   
+   public void testEjb3Mdb() throws Exception
+   {
+      TestStatus status = (TestStatus) getInitialContext().lookup(
+            "TestStatusBean/remote");
+      status.clear();
+      
+      QueueConnection cnn = null;
+      QueueSender sender = null;
+      QueueSession session = null;
+
+      Queue queue = (Queue) getInitialContext().lookup("queue/ejb3mdbsessionpoolclearQueue");
+      QueueConnectionFactory factory = getQueueConnectionFactory();
+      cnn = factory.createQueueConnection();
+      session = cnn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
+
+      TextMessage msg = session.createTextMessage("Hello World " + new Date());
+
+      sender = session.createSender(queue);
+      System.out.println(new Date() + "*** Sending 1" );
+      sender.send(msg);
+      session.close();
+      cnn.close();
+      
+      Thread.sleep(2000);
+      
+      MBeanServerConnection server = getServer();
+      ObjectName destinationManager = new ObjectName("jboss.mq:service=DestinationManager");
+      Object[] params = {};
+      String[] sig = {};
+      System.out.println(new Date() + "*** Stopping DestinationManager");
+      Object success = server.invoke(destinationManager, "stop", params, sig);
+      
+      Thread.sleep(2000);
+      
+      System.out.println(new Date() + "*** Starting DestinationManager");
+      success = server.invoke(destinationManager, "start", params, sig);
+
+      Thread.sleep(5 * 1000);
+      
+      assertEquals(1, status.queueFired());
+      
+      cnn = factory.createQueueConnection();
+      session = cnn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
+
+      msg = session.createTextMessage("Hello World " + new Date());
+
+      sender = session.createSender(queue);
+      
+      sender.send(msg);
+      System.out.println(new Date() + "*** Sending 2");
+      session.close();
+      cnn.close();
+      
+      Thread.sleep(10 * 1000);
+      
+      assertEquals(2, status.queueFired());
+   }
+
+
+   protected QueueConnectionFactory getQueueConnectionFactory()
+         throws Exception
+   {
+      try
+      {
+         return (QueueConnectionFactory) getInitialContext().lookup(
+               "ConnectionFactory");
+      } catch (NamingException e)
+      {
+         return (QueueConnectionFactory) getInitialContext().lookup(
+               "java:/ConnectionFactory");
+      }
+   }
+
+   protected InitialContext getInitialContext() throws Exception
+   {
+      return InitialContextFactory.getInitialContext();
+   }
+
+   public static Test suite() throws Exception
+   {
+      return getDeploySetup(MDBUnitTestCase.class, 
+            "mdbsessionpoolclear-test.ejb3, mdbsessionpoolclear-test.jar");
+   }
+
+}
\ No newline at end of file

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/ejb/plugins/jms/JMSContainerInvoker.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/ejb/plugins/jms/JMSContainerInvoker.java	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/ejb/plugins/jms/JMSContainerInvoker.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -145,6 +145,15 @@
 
    /** If Dead letter queue should be used or not. */
    protected boolean useDLQ = false;
+   
+   /** The forceClearOnShutdown */
+   protected boolean forceClearOnShutdown = false;
+   
+   /** The clearPoolInterval */
+   protected long forceClearInterval = 30000;
+   
+   /** The forceClearAttempts */
+   protected int forceClearAttempts = 5;
 
    /**
     * JNDI name of the provider adapter.
@@ -258,6 +267,49 @@
    {
       this.maxMessagesNr = maxMessages;
    }
+   
+   public int getNumActiveSessions()
+   {
+      if (pool instanceof org.jboss.jms.asf.StdServerSessionPool)
+      {
+         org.jboss.jms.asf.StdServerSessionPool stdPool = (org.jboss.jms.asf.StdServerSessionPool)pool;
+         return stdPool.getNumActiveSessions();
+      }
+      
+      return -1;
+   }
+   
+   public void setForceClearOnShutdown(boolean forceClear)
+   {
+      this.forceClearOnShutdown = forceClear;
+      
+   }   
+   
+   public boolean isForceClearOnShutdown()
+   {
+      return this.forceClearOnShutdown;
+   }
+   
+   public long getForceClearOnShutdownInterval()
+   {
+      return this.forceClearInterval;
+   }
+   
+   public void setForceClearOnShutdownInterval(long forceClearOnShutdownInterval)
+   {
+      this.forceClearInterval = forceClearOnShutdownInterval;
+   }
+   
+   public int getForceClearAttempts()
+   {
+      return forceClearAttempts;
+   }
+   
+   public void setForceClearAttempts(int forceClearAttempts)
+   {
+      this.forceClearAttempts = forceClearAttempts;
+      
+   }
 
    public MessageDrivenMetaData getMetaData()
    {
@@ -402,6 +454,50 @@
 
       try
       {
+         String forceClear = MetaData.getElementContent(MetaData.getUniqueChild(element, "ForceClearOnShutdown"));
+         if(forceClear != null)
+         {
+            forceClearOnShutdown = ("false".equalsIgnoreCase(forceClear)) ? false : true;
+            
+         }
+         
+      }catch(Exception ignore)
+      {
+         
+      }
+
+      try
+      {
+         String clearInterval = MetaData.getElementContent(MetaData.getUniqueChild(element, "ForceClearInterval"));
+         
+         if(clearInterval != null)
+         {
+            forceClearInterval = new Long(clearInterval).longValue();
+            
+         }
+               
+      }catch(Exception ignore)
+      {
+         
+      }
+
+      try
+      {
+         String attempts = MetaData.getElementContent(MetaData.getUniqueChild(element, "ForceClearAttempts"));
+         
+         if(attempts != null)
+         {
+            forceClearAttempts = new Integer(attempts).intValue();
+            
+         }
+      
+      }catch(Exception ignore)
+      {
+         
+      }
+
+      try
+      {
          String keepAliveMillis = MetaData.getElementContent
             (MetaData.getUniqueChild(element, "KeepAliveMillis"));
          keepAlive = Integer.parseInt(keepAliveMillis);
@@ -1168,7 +1264,7 @@
             context.lookup(serverSessionPoolFactoryJNDI);
          
          // the create the pool
-         pool = factory.getServerSessionPool(destination, connection, minSession, maxSession, keepAlive, isTransacted, ack, !isContainerManagedTx || isNotSupportedTx, listener);
+         pool = factory.getServerSessionPool(destination, connection, minSession, maxSession, keepAlive, forceClearOnShutdown, forceClearInterval, forceClearAttempts, isTransacted, ack, !isContainerManagedTx || isNotSupportedTx, listener);
       }
       finally
       {

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/ejb/plugins/jms/JMSContainerInvokerMBean.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/ejb/plugins/jms/JMSContainerInvokerMBean.java	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/ejb/plugins/jms/JMSContainerInvokerMBean.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -58,7 +58,7 @@
     * @param maxPoolSize the size
     */
    void setMaxPoolSize(int maxPoolSize);
-
+   
    /**
     * Get the keep alive millis
     * 
@@ -74,6 +74,56 @@
    void setKeepAliveMillis(long keepAlive);
 
    /**
+    * FIXME Comment this
+    * 
+    * @return
+    */
+   boolean isForceClearOnShutdown();
+   
+   /**
+    * FIXME Comment this
+    * 
+    * @param forceClear
+    */
+   void setForceClearOnShutdown(boolean forceClear);
+   
+   /**
+    * FIXME Comment this
+    * 
+    * @return
+    */
+   long getForceClearOnShutdownInterval();
+   
+   /**
+    * FIXME Comment this
+    * 
+    * @param forceClearOnShutdownInterval
+    */
+   void setForceClearOnShutdownInterval(long forceClearOnShutdownInterval);
+   
+   /**
+    * FIXME Comment this
+    * 
+    * @return
+    */
+   int getForceClearAttempts();
+   
+   /**
+    * FIXME Comment this
+    * 
+    * @param forceClearAttempts
+    */
+   void setForceClearAttempts(int forceClearAttempts);
+   
+   /**
+    * FIXME Comment this
+    * 
+    * @return
+    */
+   int getNumActiveSessions();
+
+
+   /**
     * Get the maximum number of messages
     * 
     * @return the number of messages

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/ServerSessionPoolFactory.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/ServerSessionPoolFactory.java	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/ServerSessionPoolFactory.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -77,6 +77,9 @@
     * @param minSession the minimum number of sessions
     * @param maxSession the maximum number of sessions
     * @param keepAlive the time to keep sessions alive
+    * @param forceClear whether or not to force clearing the pool
+    * @param forceClearInterval the interval to wait between pool clearing attempts
+    * @param forceClearAttempts the number of attempts for clearing the pool
     * @param isTransacted whether the pool is transacted
     * @param ack the acknowledegement method
     * @param listener the listener
@@ -85,6 +88,6 @@
     * @throws JMSException for any error
     */
    ServerSessionPool getServerSessionPool(Destination destination, Connection con, int minSession, int maxSession,
-         long keepAlive, boolean isTransacted, int ack, boolean useLocalTX, MessageListener listener)
+         long keepAlive, boolean forceClear, long forceClearInterval, int forceClearAttempts,boolean isTransacted, int ack, boolean useLocalTX, MessageListener listener)
          throws JMSException;
 }
\ No newline at end of file

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSession.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSession.java	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSession.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -55,10 +55,10 @@
    private StdServerSessionPool serverSessionPool;
 
    /** Our session resource. */
-   private Session session;
+   protected Session session;
 
    /** Our XA session resource. */
-   private XASession xaSession;
+   protected XASession xaSession;
 
    /** The transaction manager that we will use for transactions. */
    private TransactionManager tm;
@@ -103,7 +103,7 @@
     * @param useLocalTX       Will this session be used in a global TX (we can optimize with 1 phase commit)
     * @throws JMSException Transation manager was not found.
     */
-   StdServerSession(final StdServerSessionPool pool,
+   public StdServerSession(final StdServerSessionPool pool,
                     final Session session,
                     final XASession xaSession,
                     final MessageListener delegateListener,

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSessionPool.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSessionPool.java	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSessionPool.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -70,41 +70,49 @@
    private int minSize;
 
    /** The size of the pool. */
-   private int poolSize;
+   protected int poolSize;
 
    /** The message acknowledgment mode. */
-   private int ack;
+   protected int ack;
 
    /** Is the bean container managed? */
-   private boolean useLocalTX;
+   protected boolean useLocalTX;
 
    /** True if this is a transacted session. */
-   private boolean transacted;
+   protected boolean transacted;
 
    /** The destination. */
-   private Destination destination;
+   protected Destination destination;
 
    /** The session connection. */
-   private Connection con;
+   protected Connection con;
 
    /** The message listener for the session. */
-   private MessageListener listener;
+   protected MessageListener listener;
 
    /** The list of ServerSessions. */
-   private List sessionPool;
+   protected List sessionPool;
 
    /** The executor for processing messages? */
    private PooledExecutor executor;
 
    /** Used to signal when the Pool is being closed down */
    private boolean closing = false;
+   
+   /** The forceClear */
+   private boolean forceClear = false;
+   
+   /** The forceClearInterval */
+   private long forceClearInterval = 30000;
+   
+   private int forceClearAttempts = 5;
 
    /** Used during close down to wait for all server sessions to be returned and closed. */
-   private int numServerSessions = 0;
+   protected int numServerSessions = 0;
 
-   private XidFactoryMBean xidFactory;
+   protected XidFactoryMBean xidFactory;
 
-   private TransactionManager tm;
+   protected TransactionManager tm;
 
    /**
     * Construct a <tt>StdServerSessionPool</tt>. Note the maxSession parameter controls
@@ -134,6 +142,9 @@
                                final int minSession,
                                final int maxSession,
                                final long keepAlive,
+                               final boolean forceClear,
+                               final long forceClearInterval,
+                               final int forceClearAttempts,
                                final XidFactoryMBean xidFactory,
                                final TransactionManager tm)
       throws JMSException
@@ -146,6 +157,9 @@
       this.minSize = minSession;
       this.poolSize = maxSession;
       this.sessionPool = new ArrayList(maxSession);
+      this.forceClear = forceClear;
+      this.forceClearInterval = forceClearInterval;
+      this.forceClearAttempts = forceClearAttempts;
       this.useLocalTX = useLocalTX;
       this.xidFactory = xidFactory;
       this.tm = tm;
@@ -203,13 +217,24 @@
       }
       catch (Exception e)
       {
+         log.info("********* Failed to get a server session " + e.getClass());
          throw new JMSException("Failed to get a server session: " + e);
       }
 
       if( log.isTraceEnabled() )
          log.trace("using server session: " + session);
+      log.info("********* returning a server session " + sessionPool.size());
       return session;
    }
+   
+   /**
+    * Return number of active sessions. For use only for read-only jmx view.
+    * see JBPAPP-387
+    */
+   public int getNumActiveSessions()
+   {
+      return this.numServerSessions;
+   }
 
    /**
     * Clear the pool, clear out both threads and ServerSessions,
@@ -226,7 +251,7 @@
          closing = true;
 
          log.debug("Clearing " + sessionPool.size() + " from ServerSessionPool");
-
+       
          Iterator iter = sessionPool.iterator();
          while (iter.hasNext())
          {
@@ -246,14 +271,38 @@
       //wait for all server sessions to be returned.
       synchronized (sessionPool)
       {
-         while (numServerSessions > 0)
+         int attempts = 0;
+         if(forceClear)
          {
-            try
+            log.trace("Force clear behavior in effect. Waiting for " + forceClearInterval + " milliseconds for " + forceClearAttempts + " attempts.");
+  
+            while((numServerSessions > 0) && (attempts < forceClearAttempts))
             {
-               sessionPool.wait();
+               try
+               {
+                  sessionPool.wait(forceClearInterval);
+                  log.trace("Clear attempt " + attempts); 
+                  ++attempts;               
+            
+               }catch(InterruptedException ignore)
+               {
+                  
+               }
+            
             }
-            catch (InterruptedException ignore)
+            
+         }
+         else
+         {
+            while (numServerSessions > 0)
             {
+               try
+               {
+                  sessionPool.wait();
+               }
+               catch (InterruptedException ignore)
+               {
+               }
             }
          }
       }
@@ -297,6 +346,7 @@
             if (numServerSessions == 0)
             {
                //notify clear thread.
+               new Exception().printStackTrace();
                sessionPool.notifyAll();
             }
          }
@@ -310,7 +360,7 @@
       }
    }
 
-   private void create() throws JMSException
+   protected void create() throws JMSException
    {
       for (int index = 0; index < poolSize; index++)
       {

Modified: branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSessionPoolFactory.java
===================================================================
--- branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSessionPoolFactory.java	2007-11-02 19:09:42 UTC (rev 66691)
+++ branches/JBPAPP_4_2_0_GA_CP01_JBPAPP-364/server/src/main/org/jboss/jms/asf/StdServerSessionPoolFactory.java	2007-11-02 19:44:42 UTC (rev 66692)
@@ -47,9 +47,9 @@
    /** The name of this factory. */
    private String name;
 
-   private XidFactoryMBean xidFactory;
+   protected XidFactoryMBean xidFactory;
 
-   private TransactionManager transactionManager;
+   protected TransactionManager transactionManager;
 
    public StdServerSessionPoolFactory()
    {
@@ -86,9 +86,9 @@
       return transactionManager;
    }
 
-   public ServerSessionPool getServerSessionPool(Destination destination, Connection con, int minSession, int maxSession, long keepAlive, boolean isTransacted, int ack, boolean useLocalTX, MessageListener listener) throws JMSException
+   public ServerSessionPool getServerSessionPool(Destination destination, Connection con, int minSession, int maxSession, long keepAlive, boolean forceClear, long forceClearInterval, int forceClearAttempts, boolean isTransacted, int ack, boolean useLocalTX, MessageListener listener) throws JMSException
    {
-      ServerSessionPool pool = new StdServerSessionPool(destination, con, isTransacted, ack, useLocalTX, listener, minSession, maxSession, keepAlive, xidFactory, transactionManager);
+      ServerSessionPool pool = new StdServerSessionPool(destination, con, isTransacted, ack, useLocalTX, listener, minSession, maxSession, keepAlive, forceClear, forceClearInterval, forceClearAttempts, xidFactory, transactionManager);
       return pool;
    }
 }




More information about the jboss-cvs-commits mailing list