[jboss-cvs] JBoss Messaging SVN: r1368 - in trunk: . docs docs/examples/http/src/org/jboss/example/jms/http docs/gettingstarted/en/modules src src/etc src/etc/server/default/deploy src/main/org/jboss/jms/client src/main/org/jboss/jms/client/container src/main/org/jboss/jms/client/delegate src/main/org/jboss/jms/client/remoting src/main/org/jboss/jms/client/state src/main/org/jboss/jms/delegate src/main/org/jboss/jms/message src/main/org/jboss/jms/server/connectionfactory src/main/org/jboss/jms/server/endpoint src/main/org/jboss/jms/server/endpoint/advised src/main/org/jboss/jms/tx src/main/org/jboss/messaging/core src/main/org/jboss/messaging/core/local src/main/org/jboss/messaging/core/message src/main/org/jboss/messaging/core/tx tests tests/bin tests/etc tests/lib tests/smoke tests/src/org/jboss/test/messaging/core/plugin tests/src/org/jboss/test/messaging/jms tests/src/org/jboss/test/messaging/jms/crash tests/src/org/jboss/test/messaging/jms/message tests/src/org/jboss/test! /messaging/jms/server/destination tests/src/org/jboss/test/messaging/tools

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Wed Sep 27 03:56:07 EDT 2006


Author: ovidiu.feodorov at jboss.com
Date: 2006-09-27 03:55:32 -0400 (Wed, 27 Sep 2006)
New Revision: 1368

Added:
   trunk/src/etc/server/default/deploy/mssql-persistence-service.xml
   trunk/tests/lib/README
   trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriberTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/JCAWrapperTest.java
Removed:
   trunk/src/resources/
   trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriptionTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/XATransactionTest.java
Modified:
   trunk/.classpath
   trunk/build-messaging.xml
   trunk/build-thirdparty.xml
   trunk/docs/README.html
   trunk/docs/examples/http/src/org/jboss/example/jms/http/HttpExample.java
   trunk/docs/gettingstarted/en/modules/configuration.xml
   trunk/messaging.iml
   trunk/messaging.ipr
   trunk/src/etc/aop-messaging-client.xml
   trunk/src/main/org/jboss/jms/client/Closeable.java
   trunk/src/main/org/jboss/jms/client/JBossConnection.java
   trunk/src/main/org/jboss/jms/client/container/AsfAspect.java
   trunk/src/main/org/jboss/jms/client/container/ClosedInterceptor.java
   trunk/src/main/org/jboss/jms/client/container/ConnectionAspect.java
   trunk/src/main/org/jboss/jms/client/container/ProducerAspect.java
   trunk/src/main/org/jboss/jms/client/container/SessionAspect.java
   trunk/src/main/org/jboss/jms/client/container/StateCreationAspect.java
   trunk/src/main/org/jboss/jms/client/container/TransactionAspect.java
   trunk/src/main/org/jboss/jms/client/delegate/ClientBrowserDelegate.java
   trunk/src/main/org/jboss/jms/client/delegate/ClientConnectionDelegate.java
   trunk/src/main/org/jboss/jms/client/delegate/ClientConnectionFactoryDelegate.java
   trunk/src/main/org/jboss/jms/client/delegate/ClientConsumerDelegate.java
   trunk/src/main/org/jboss/jms/client/delegate/ClientProducerDelegate.java
   trunk/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java
   trunk/src/main/org/jboss/jms/client/delegate/DelegateSupport.java
   trunk/src/main/org/jboss/jms/client/remoting/CallbackServerFactory.java
   trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java
   trunk/src/main/org/jboss/jms/client/state/SessionState.java
   trunk/src/main/org/jboss/jms/delegate/SessionDelegate.java
   trunk/src/main/org/jboss/jms/message/JBossMessage.java
   trunk/src/main/org/jboss/jms/message/MessageIdGeneratorFactory.java
   trunk/src/main/org/jboss/jms/message/MessageProxy.java
   trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/SessionEndpoint.java
   trunk/src/main/org/jboss/jms/server/endpoint/advised/BrowserAdvised.java
   trunk/src/main/org/jboss/jms/server/endpoint/advised/ConnectionAdvised.java
   trunk/src/main/org/jboss/jms/server/endpoint/advised/ConsumerAdvised.java
   trunk/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java
   trunk/src/main/org/jboss/jms/tx/AckInfo.java
   trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java
   trunk/src/main/org/jboss/jms/tx/ResourceManagerFactory.java
   trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
   trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java
   trunk/src/main/org/jboss/messaging/core/message/RoutableSupport.java
   trunk/src/main/org/jboss/messaging/core/tx/Transaction.java
   trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java
   trunk/tests/bin/loop
   trunk/tests/build.xml
   trunk/tests/etc/log4j.trace.xml
   trunk/tests/etc/log4j.xml
   trunk/tests/lib/jms-ra.jar
   trunk/tests/smoke/build.xml
   trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/CreateTwoClientOnServerCommand.java
   trunk/tests/src/org/jboss/test/messaging/jms/JMSTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/MiscellaneousTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/SessionTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/TransactedSessionTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/WireFormatTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/crash/ClientCrashTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/crash/ClientCrashTwoConnectionsTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/message/JMSXDeliveryCountTest.java
   trunk/tests/src/org/jboss/test/messaging/jms/server/destination/QueueManagementTest.java
   trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
Log:
merging Branch_1_0 (-r 1244:1367)

Modified: trunk/.classpath
===================================================================
--- trunk/.classpath	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/.classpath	2006-09-27 07:55:32 UTC (rev 1368)
@@ -12,9 +12,6 @@
 	<classpathentry kind="lib" path="lib/jboss-system.jar"/>
 	<classpathentry kind="lib" path="lib/jboss-transaction.jar"/>
 	<classpathentry kind="lib" path="lib/jnp-client.jar"/>
-	<classpathentry kind="lib" path="src/resources/clester.jar"/>
-	<classpathentry kind="lib" path="src/resources/jboss-aspect-library.jar"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/j2sdk1.4.2_09"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/common/lib/jboss-common.jar"/>
 	<classpathentry kind="lib" path="thirdparty/oswego-concurrent/lib/concurrent.jar"/>
 	<classpathentry kind="lib" path="tests/lib/jboss-common-jdbc-wrapper.jar"/>
@@ -27,13 +24,38 @@
 	<classpathentry kind="lib" path="perf/resources/jcommon-1.0.0-rc1.jar"/>
 	<classpathentry kind="lib" path="perf/resources/jfreechart-1.0.0-rc1.jar"/>
 	<classpathentry kind="lib" path="thirdparty/apache-log4j/lib/log4j.jar"/>
-	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jboss-aop.jar"/>
+	<classpathentry sourcepath="/home/clebert/workspaces/jboss-head/aop/src/main" kind="lib" path="thirdparty/jboss/aop/lib/jboss-aop.jar"/>
 	<classpathentry kind="lib" path="thirdparty/junit/lib/junit.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/profiler/jvmti/lib/jboss-profiler-jvmti.jar"/>
 	<classpathentry kind="lib" path="thirdparty/hsqldb/lib/hsqldb.jar"/>
-	<classpathentry kind="lib" path="C:/tools/apache-ant-1.6.5/lib/ant-junit.jar"/>
 	<classpathentry kind="lib" path="thirdparty/apache-logging/lib/commons-logging.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/remoting/lib/jboss-remoting.jar"/>
 	<classpathentry kind="lib" path="thirdparty/jboss/serialization/lib/jboss-serialization.jar"/>
+	<classpathentry kind="var" path="ANT_HOME/ant-junit.jar"/>
+	<classpathentry sourcepath="/JBossRemoting" kind="lib" path="thirdparty/jboss/remoting/lib/jboss-remoting.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/serialization/lib/jboss-serialization.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="thirdparty/sun-javacc/lib/javacc.jar"/>
+	<classpathentry kind="lib" path="thirdparty/apache-log4j/lib/snmpTrapAppender.jar"/>
+	<classpathentry kind="lib" path="thirdparty/apache-xerces/lib/resolver.jar"/>
+	<classpathentry kind="lib" path="thirdparty/apache-xerces/lib/xercesImpl.jar"/>
+	<classpathentry kind="lib" path="thirdparty/apache-xerces/lib/xml-apis.jar"/>
+	<classpathentry kind="lib" path="thirdparty/dom4j/lib/dom4j.jar"/>
+	<classpathentry kind="lib" path="thirdparty/javassist/lib/javassist.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/common-softvaluehashmap.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jboss-aop-jdk50.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jboss-aop-jdk50-client.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jboss-aspect-jdk50-client.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jdk14-pluggable-instrumentor.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jrockit-pluggable-instrumentor.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/pluggable-instrumentor.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/common/lib/jboss-archive-browsing.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/common/lib/jboss-common-client.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/common/lib/namespace.jar"/>
+	<classpathentry kind="lib" path="thirdparty/jboss/jbossxb/lib/jboss-xml-binding.jar"/>
+	<classpathentry kind="lib" path="thirdparty/retrotranslator/lib/backport-util-concurrent.jar"/>
+	<classpathentry kind="lib" path="thirdparty/retrotranslator/lib/retrotranslator-runtime.jar"/>
+	<classpathentry kind="lib" path="thirdparty/retrotranslator/lib/retrotranslator-transformer.jar"/>
+	<classpathentry kind="lib" path="thirdparty/trove/lib/trove.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>

Modified: trunk/build-messaging.xml
===================================================================
--- trunk/build-messaging.xml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/build-messaging.xml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -686,6 +686,7 @@
    </target>
 
    <target name="source-bundle">
+      <mkdir dir="${build.lib}"/>
       <zip destfile="${build.lib}/jboss-messaging-${module.version}-src.zip">
          <zipfileset dir="${project.root}" prefix="jboss-messaging-${module.version}-src">
             <exclude name="**/.svn"/>

Modified: trunk/build-thirdparty.xml
===================================================================
--- trunk/build-thirdparty.xml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/build-thirdparty.xml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -89,8 +89,8 @@
       <componentref name="trove" version="1.0.2"/>
       <componentref name="jboss/common" version="snapshot"/>
       <componentref name="jboss/aop" version="1.5.0.GA"/>
-      <componentref name="jboss/serialization" version="1.0.2.GA"/>
-      <componentref name="jboss/remoting" version="2.0.0.GA"/>
+      <componentref name="jboss/serialization" version="1.0.3.GA"/>
+      <componentref name="jboss/remoting" version="2.2.0.Alpha2"/>
 
       <!-- Need this otherwise project doesn't build in Eclipse -->
       <componentref name="apache-logging" version="1.0.5.GA-jboss"/>

Modified: trunk/docs/README.html
===================================================================
--- trunk/docs/README.html	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/docs/README.html	2006-09-27 07:55:32 UTC (rev 1368)
@@ -7,9 +7,9 @@
 </head>
 <body>
 <h1><br>
-JBoss Messaging 1.0.1.CR4 Release Notes</h1>
+JBoss Messaging 1.0.1.CR5 Release Notes</h1>
 <br>
-August 9, 2006<br>
+September 22, 2006<br>
 <br>
 <br>
 <h2>Installation</h2>
@@ -32,74 +32,111 @@
 Notes" below.<br>
 <br>
 <h2>Release Notes </h2>
-<h2 style="margin-left: 40px;">Bug</h2>
+<h2 style="margin-left: 40px;">Bugs</h2>
 <ul style="margin-left: 40px;">
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-427">JBMESSAGING-427</a>]
-- MDB compatibility test fails with an 1.0.1.CR1 server</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-433">JBMESSAGING-433</a>]
-- MessageConsumer.receive() successfully returned although the
-acknowledgement is failed</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-434">JBMESSAGING-434</a>]
-- Client receive the server side exception</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-436">JBMESSAGING-436</a>]
-- Messages are not cloned on resend</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-440">JBMESSAGING-440</a>]
-- ConcurrentModificationException in transaction commit</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-442">JBMESSAGING-442</a>]
-- JBoss Serialization issue with readResolve</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-448">JBMESSAGING-448</a>]
-- Durable subscription state on unsubscribe</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-449">JBMESSAGING-449</a>]
-- Persisted messages not removed on acknowledgement</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-450">JBMESSAGING-450</a>]
-- Queue/Topic removeAllMessages is broken</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-451">JBMESSAGING-451</a>]
-- Closing of non recoveranle channel does not remove references</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-452">JBMESSAGING-452</a>]
-- On startup of server remaining non persistent messages are not
-cleaned properly</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-453">JBMESSAGING-453</a>]
-- QueuedExecutors not being shutdown explicitly</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-484">JBMESSAGING-484</a>]
-- org.jboss.test.messaging.jms.MessageConsumerTest.testNoLocal fails
-locally and remotely</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-487">JBMESSAGING-487</a>]
-- ssh smoke test fails on 4.0.4.GA</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-489">JBMESSAGING-489</a>]
-- stress tests fail on dual core</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-490">JBMESSAGING-490</a>]
-- Race condition on ServerConsumerEndpoint creation</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-491">JBMESSAGING-491</a>]
-- Deadlock among ServerConsumerEndpoint.lock and
-RoundRobinPointToPointRouter.receiver's locks</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-492">JBMESSAGING-492</a>]
-- DurableSubscriberTest, MessageConsumerTest timeout occasionally</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-493">JBMESSAGING-493</a>]
-- QueuedExecutor is bounded</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-500">JBMESSAGING-500</a>]
-- Intermittent race in BrowserTest::testBrowse</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-501">JBMESSAGING-501</a>]
-- Race with removeAllReferences</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-503">JBMESSAGING-503</a>]
-- QueueManagementTest::testMessageCount</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-277">JBMESSAGING-277</a>]
+- Setting remoting lease period to -1 breaks ASF</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-410">JBMESSAGING-410</a>]
+- java:/JmsXA in no-tx context does not work the same way as JBossMQ</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-424">JBMESSAGING-424</a>]
+- Cannot access the first message when starting the JMS subscriber</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-428">JBMESSAGING-428</a>]
+- Stress tests fail</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-432">JBMESSAGING-432</a>]
+- One connection per unique JMS server leak</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-477">JBMESSAGING-477</a>]
+- Messages are left in the Messages table after retry message is
+printed and are retried every time the server is restarted</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-499">JBMESSAGING-499</a>]
+- get-test-execution-classpath assumes windows</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-506">JBMESSAGING-506</a>]
+- On restart, the channel mapper throws java.sql.SQLException: Invalid
+column index</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-507">JBMESSAGING-507</a>]
+- JDBCChannelMapper ignores CreateTablesOnStartup value from
+xxx-peristence-service.xml</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-508">JBMESSAGING-508</a>]
+- The MessageCount property on the queue appears to climb to the
+FullSize value, then stop.</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-510">JBMESSAGING-510</a>]
+- JDBCChannelMapper has a createTablesOnStartup variable but no overide.</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-520">JBMESSAGING-520</a>]
+- Messages received from Receiver.receive() using an XA are never
+deleted from the database if not withing a transactional boundary.</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-521">JBMESSAGING-521</a>]
+- IllegalStateException: Cannot find delivery to cancel for 1000
+Message test.</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-525">JBMESSAGING-525</a>]
+- postgresql-persistence-service.xml contains invalid SQL syntax</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-526">JBMESSAGING-526</a>]
+- JMSRedelivered flag not correctly set on true in certain redelivery
+scenarios</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-531">JBMESSAGING-531</a>]
+- ServerPeer destroyTopic()/destroyQueue() must not throw exception on
+non-existent destinations, but return false.</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-532">JBMESSAGING-532</a>]
+- jboss-messaging.jar inappropriately packs service deployment
+descriptors</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-533">JBMESSAGING-533</a>]
+- Class not found when creating durable subscription from a different
+classloading domain</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-535">JBMESSAGING-535</a>]
+- Possible race condition in initialization of the server-side Remoting
+callback client:
+"org.jboss.remoting.ServerInvoker$InvalidStateException: Can not
+process invocation request since is not in started state"</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-536">JBMESSAGING-536</a>]
+- The CallbackServer cannot be contacted for some particular network
+interface configurations</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-538">JBMESSAGING-538</a>]
+- The MessageCount property on the queue appears to climb to the
+FullSize value, then stop</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-541">JBMESSAGING-541</a>]
+- If the first opened connections is closed, Remoting Lease doesn't
+work any more</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-542">JBMESSAGING-542</a>]
+- Closing connection inside MessageListener's onMessage() causes
+deadlock</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-545">JBMESSAGING-545</a>]
+- Transaction edge cases and memory leak</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-546">JBMESSAGING-546</a>]
+- org.jboss.test.messaging.jms.DurableSubscriberTest times out</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-549">JBMESSAGING-549</a>]
+- Remoting 2.2.0.Alpha1 breaks 2 crash tests</li>
 </ul>
-<h2 style="margin-left: 40px;">Feature Request</h2>
+<h2 style="margin-left: 40px;">Feature Requests</h2>
 <ul style="margin-left: 40px;">
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-476">JBMESSAGING-476</a>]
-- Reoccuring Consumer endpoint activation failed Error</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-528">JBMESSAGING-528</a>]
+- Update user manual to include details on configuring remoting's
+serverBindAddress</li>
 </ul>
-<h2 style="margin-left: 40px;">Task</h2>
+<h2 style="margin-left: 40px;">Tasks</h2>
 <ul style="margin-left: 40px;">
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-328">JBMESSAGING-328</a>]
-- Optimisation - batch messages to consumers</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-393">JBMESSAGING-393</a>]
-- Remove the serverless packages from CVS</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-403">JBMESSAGING-403</a>]
-- The Getting Started guide contains obsolete version numbers</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-441">JBMESSAGING-441</a>]
-- Refactoring of message delivery</li>
-  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-481">JBMESSAGING-481</a>]
-- Implement a round robin routing strategy for queues and subscriptions</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-431">JBMESSAGING-431</a>]
+- Socket transports should use configurable port</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-472">JBMESSAGING-472</a>]
+- Test and use remoting 2.0.0.CR1 (or 2.0.0.GA if it's released in time)</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-485">JBMESSAGING-485</a>]
+- CTSMiscellaneousTest.testContestedQueueOnRollback temporarily
+commented out</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-502">JBMESSAGING-502</a>]
+- Create a MSSQL persistence manager config</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-504">JBMESSAGING-504</a>]
+- Release with a tagged JBossSerialization jar</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-529">JBMESSAGING-529</a>]
+- Install TCK5 locally and fix all errors that prevent Messaging from
+passing</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-530">JBMESSAGING-530</a>]
+- Make sure QA cruisecontrol tests Branch_1_0</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-534">JBMESSAGING-534</a>]
+- Create a new "messaging" subdirectory in repository.jboss.com and
+start uploading messaging artifacts there</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-547">JBMESSAGING-547</a>]
+- Upgrade JBossSerialization to 1.0.3.GA</li>
+  <li>[<a href="http://jira.jboss.com/jira/browse/JBMESSAGING-551">JBMESSAGING-551</a>]
+- Upgrade JBoss Remoting</li>
 </ul>
+<br>
+<hr style="width: 100%; height: 2px;">
 </body>
 </html>

Modified: trunk/docs/examples/http/src/org/jboss/example/jms/http/HttpExample.java
===================================================================
--- trunk/docs/examples/http/src/org/jboss/example/jms/http/HttpExample.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/docs/examples/http/src/org/jboss/example/jms/http/HttpExample.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -23,7 +23,7 @@
 
 import org.jboss.example.jms.common.ExampleSupport;
 
-import javax.naming.InitialContext;
+import javax.naming.InitialContext; 
 import javax.jms.TextMessage;
 import javax.jms.Session;
 import javax.jms.ConnectionFactory;

Modified: trunk/docs/gettingstarted/en/modules/configuration.xml
===================================================================
--- trunk/docs/gettingstarted/en/modules/configuration.xml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/docs/gettingstarted/en/modules/configuration.xml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -669,5 +669,9 @@
 		Use java -Djboss.messaging.callback.bind.address=YourHost - That will determine the callBack host in your client.
       </para>
 
+      <para>
+		The client port will be selected randomly for any non used port. But if you defined -Djboss.messaging.callback.bind.port=NumericPort in your System Properties that number is going to be used for the call back client port.
+      </para>
+
   </section>
 </chapter>

Modified: trunk/messaging.iml
===================================================================
--- trunk/messaging.iml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/messaging.iml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -113,7 +113,9 @@
           <root url="jar://$MODULE_DIR$/tests/lib/jms-ra.jar!/" />
         </CLASSES>
         <JAVADOC />
-        <SOURCES />
+        <SOURCES>
+          <root url="file://$MODULE_DIR$/../../jboss-4.0.4.GA-src/connector/src/main" />
+        </SOURCES>
       </library>
     </orderEntry>
     <orderEntry type="module-library">
@@ -172,7 +174,7 @@
         </CLASSES>
         <JAVADOC />
         <SOURCES>
-          <root url="file://$MODULE_DIR$/../../cvs/JBossRemoting-2.0.0.GA/src/main" />
+          <root url="file://$MODULE_DIR$/../../cvs/JBossRemoting-2.2.0.Alpha1/src/main" />
         </SOURCES>
       </library>
     </orderEntry>

Modified: trunk/messaging.ipr
===================================================================
--- trunk/messaging.ipr	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/messaging.ipr	2006-09-27 07:55:32 UTC (rev 1368)
@@ -188,6 +188,8 @@
   <component name="ProjectModuleManager">
     <modules>
       <module fileurl="file://$PROJECT_DIR$/messaging.iml" filepath="$PROJECT_DIR$/messaging.iml" />
+      <module fileurl="file://C:/work/playground/jms/messaging/mdb/messaging-mdb.iml" filepath="C:/work/playground/jms/messaging/mdb/messaging-mdb.iml" />
+      <module fileurl="file://C:/work/playground/jms/messaging/topic/topic.iml" filepath="C:/work/playground/jms/messaging/topic/topic.iml" />
     </modules>
   </component>
   <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="false" project-jdk-name="1.4" />

Modified: trunk/src/etc/aop-messaging-client.xml
===================================================================
--- trunk/src/etc/aop-messaging-client.xml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/etc/aop-messaging-client.xml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -122,7 +122,10 @@
    </bind>   
    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientSessionDelegate->redeliver(..))">
       <advice name="handleRedeliver" aspect="org.jboss.jms.client.container.SessionAspect"/>
-   </bind>    
+   </bind>
+   <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientSessionDelegate->closing())">
+      <advice name="handleClosing" aspect="org.jboss.jms.client.container.SessionAspect"/>         
+   </bind>
    <bind pointcut="execution(* org.jboss.jms.client.delegate.ClientSessionDelegate->close())">
       <advice name="handleClose" aspect="org.jboss.jms.client.container.SessionAspect"/>         
    </bind>   

Copied: trunk/src/etc/server/default/deploy/mssql-persistence-service.xml (from rev 1367, branches/Branch_1_0/src/etc/server/default/deploy/mssql-persistence-service.xml)

Modified: trunk/src/main/org/jboss/jms/client/Closeable.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/Closeable.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/Closeable.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -28,13 +28,13 @@
  * Implemented by JMS classes that can be closed
  * 
  * @author <a href="mailto:adrian at jboss.org>Adrian Brock</a>
+ * @author <a href="mailto:ovidiu at jboss.org>Ovidiu Feodorov</a>
  *
  * @version $Revision$
  */
 public interface Closeable
 {
    /**
-    * 
     * Close the instance
     * 
     * @throws JMSException
@@ -47,5 +47,7 @@
     * @throws JMSException
     */
    void closing() throws JMSException;
+
+   boolean isClosed();
   
 }

Modified: trunk/src/main/org/jboss/jms/client/JBossConnection.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/JBossConnection.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/JBossConnection.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -61,27 +61,27 @@
     Connection, QueueConnection, TopicConnection,
     XAConnection, XAQueueConnection, XATopicConnection, Serializable
 {
-   
+
    // Constants -----------------------------------------------------
    private static final long serialVersionUID = -3715868654823177898L;
-   
+
    static final int TYPE_GENERIC_CONNECTION = 0;
    static final int TYPE_QUEUE_CONNECTION = 1;
    static final int TYPE_TOPIC_CONNECTION = 2;
-   
+
    // Static --------------------------------------------------------
 
    // Attributes ----------------------------------------------------
 
    protected ConnectionDelegate delegate;
-   private int connectionType;   
+   private int connectionType;
 
    // Constructors --------------------------------------------------
 
    public JBossConnection(ConnectionDelegate delegate, int connectionType)
    {
       this.delegate = delegate;
-      this.connectionType = connectionType;      
+      this.connectionType = connectionType;
    }
 
    // Connection implementation -------------------------------------
@@ -146,7 +146,7 @@
                                                              String messageSelector,
                                                              ServerSessionPool sessionPool,
                                                              int maxMessages) throws JMSException
-   {      
+   {
       // As spec. section 4.11
       if (connectionType == TYPE_QUEUE_CONNECTION)
       {
@@ -156,23 +156,23 @@
       return delegate.
          createConnectionConsumer(topic, subscriptionName, messageSelector, sessionPool, maxMessages);
    }
-   
+
    // QueueConnection implementation ---------------------------------
 
    public QueueSession createQueueSession(boolean transacted,
                                           int acknowledgeMode) throws JMSException
-   {    
+   {
        return createSessionInternal(transacted, acknowledgeMode, false,
                                     JBossSession.TYPE_QUEUE_SESSION);
    }
-   
+
    public ConnectionConsumer createConnectionConsumer(Queue queue, String messageSelector,
                                                       ServerSessionPool sessionPool,
                                                       int maxMessages) throws JMSException
     {
       return delegate.createConnectionConsumer(queue, null, messageSelector, sessionPool, maxMessages);
     }
-   
+
    // TopicConnection implementation ---------------------------------
 
    public TopicSession createTopicSession(boolean transacted,
@@ -181,35 +181,35 @@
       return createSessionInternal(transacted, acknowledgeMode, false,
                                    JBossSession.TYPE_TOPIC_SESSION);
    }
-   
+
    public ConnectionConsumer createConnectionConsumer(Topic topic, String messageSelector,
                                                       ServerSessionPool sessionPool,
                                                       int maxMessages) throws JMSException
    {
       return delegate.createConnectionConsumer(topic, null, messageSelector, sessionPool, maxMessages);
    }
-   
+
    // XAConnection implementation -------------------------------------
 
    public XASession createXASession() throws JMSException
-   {      
+   {
        return createSessionInternal(true, Session.SESSION_TRANSACTED, true,
                                     JBossSession.TYPE_GENERIC_SESSION);
    }
-   
+
    // XAQueueConnection implementation ---------------------------------
 
    public XAQueueSession createXAQueueSession() throws JMSException
-   {       
+   {
       return createSessionInternal(true, Session.SESSION_TRANSACTED, true,
                                    JBossSession.TYPE_QUEUE_SESSION);
 
    }
-   
+
    // XATopicConnection implementation ---------------------------------
 
    public XATopicSession createXATopicSession() throws JMSException
-   {      
+   {
       return createSessionInternal(true, Session.SESSION_TRANSACTED, true,
                                    JBossSession.TYPE_TOPIC_SESSION);
 
@@ -221,14 +221,14 @@
    {
       return "JBossConnection->" + delegate;
    }
-   
+
    public String getRemotingClientSessionId()
    {
       ConnectionState state = (ConnectionState)((ClientConnectionDelegate)delegate).getState();
-      
+
       return state.getRemotingConnection().getInvokingClient().getSessionId();
    }
-   
+
    public ConnectionDelegate getDelegate()
    {
       return delegate;
@@ -237,7 +237,7 @@
    // Package protected ---------------------------------------------
 
    // Protected -----------------------------------------------------
-   
+
    protected JBossSession createSessionInternal(boolean transacted, int acknowledgeMode,
                                                 boolean isXA, int type) throws JMSException
    {
@@ -262,6 +262,22 @@
       }
    }
 
+   // Temporarily commented out as it seems to produce random test failures
+   // See http://jira.jboss.org/jira/browse/JBMESSAGING-548
+   
+//   protected void finalize() throws Throwable
+//   {
+//      super.finalize();
+//
+//      // If a user hasn't explicitly closed the connection due to sloppy programming then
+//      // we close it here
+//
+//      if (!delegate.isClosed())
+//      {
+//         close();
+//      }
+//   }
+
    // Private -------------------------------------------------------
 
    // Inner classes -------------------------------------------------

Modified: trunk/src/main/org/jboss/jms/client/container/AsfAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/AsfAspect.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/container/AsfAspect.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -39,13 +39,13 @@
 import org.jboss.jms.destination.JBossDestination;
 import org.jboss.jms.message.MessageProxy;
 import org.jboss.logging.Logger;
-import org.jgroups.protocols.JMS;
 
+
 /**
  * An aspect that implements the Application Server Facilities for concurrent processing of 
  * a consumer's messages.
  * 
- * @see JMS 1.1 spec. section 8.2
+ * See JMS 1.1 spec. section 8.2
  * 
  * This aspect is PER_INSTANCE.
  *  
@@ -162,8 +162,7 @@
 
          if (trace) { log.trace("sending " + holder.msg + " to the message listener" ); }
          
-         MessageCallbackHandler.callOnMessage(holder.consumerDelegate, del,
-                                              sessionListener, holder.consumerID, false,
+         MessageCallbackHandler.callOnMessage(del, sessionListener, holder.consumerID, false,
                                               holder.msg, ackMode);                          
       }
       

Modified: trunk/src/main/org/jboss/jms/client/container/ClosedInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ClosedInterceptor.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/container/ClosedInterceptor.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -39,57 +39,83 @@
 
 /**
  * An interceptor for checking closed state. It waits for other invocations to complete before
- * allowing the close. I.e. it performs the function of a "valve"
+ * allowing the close. I.e. it performs the function of a "valve".
  * 
  * This interceptor is PER_INSTANCE.
  * 
  * @author <a href="mailto:adrian at jboss.org>Adrian Brock</a>
  * @author <a href="mailto:tim.fox at jboss.com>Tim Fox</a>
+ * @author <a href="mailto:ovidiu at jboss.com>Ovidiu Feodorov</a>
  *
  * $Id$
  */
-public class ClosedInterceptor  implements Interceptor
+public class ClosedInterceptor implements Interceptor
 {
    // Constants -----------------------------------------------------
    
    private static final Logger log = Logger.getLogger(ClosedInterceptor.class);
    
-   /** Not closed */
    private static final int NOT_CLOSED = 0;
-   
-   /** Closing */
    private static final int IN_CLOSING = 1;
-   
-   /** Closing */
    private static final int CLOSING = 2;
-   
-   /** Performing the close */
-   private static final int IN_CLOSE = 3;
-   
-   /** Closed */
+   private static final int IN_CLOSE = 3; // performing the close
    private static final int CLOSED = -1;
    
    // Attributes ----------------------------------------------------
    
    private boolean trace = log.isTraceEnabled();
 
-   /** The state of the object */
+   // The current state of the object guarded by this interceptor
    private int state = NOT_CLOSED;
    
-   /** The inuse count */
-   private int inuseCount = 0;
+   // The inuse count
+   private int inUseCount;
 
+   // The identity of the delegate this interceptor is associated with
+   private Integer id;
+   private String delegateType;
+
    // Static --------------------------------------------------------
+
+   public static String stateToString(int state)
+   {
+      return state == NOT_CLOSED ? "NOT_CLOSED" :
+         state == IN_CLOSING ? "IN_CLOSING" :
+            state == CLOSING ? "CLOSING" :
+               state == IN_CLOSE ? "IN_CLOSE" :
+                  state == CLOSED ? "CLOSED" : "UNKNOWN";
+   }
    
    // Constructors --------------------------------------------------
 
+   public ClosedInterceptor()
+   {
+      state = NOT_CLOSED;
+      inUseCount = 0;
+      id = null;
+   }
+
    // Public --------------------------------------------------------
 
    public String toString()
    {
-      return "ClosedInterceptor[" + Integer.toHexString(hashCode()) + "]";
+      StringBuffer sb = new StringBuffer("ClosedInterceptor.");
+      if (id == null)
+      {
+         sb.append("UNINITIALIZED");
+      }
+      else
+      {
+         sb.append(delegateType).append("[").append(id.intValue()).append("]");
+      }
+      return sb.toString();
    }
 
+   public boolean isClosed()
+   {
+      return state == IN_CLOSE || state == CLOSED;
+   }
+
    // Interceptor implementation -----------------------------------
 
    public String getName()
@@ -99,12 +125,23 @@
 
    public Object invoke(Invocation invocation) throws Throwable
    {
+      // maintain the identity of the delegate that sends invocation through this interceptor, for
+      // logging purposes. It makes sense, since it's an PER_INSTANCE interceptor
+      if (id == null)
+      {
+         getIdentity(invocation);
+      }
+
       String methodName = ((MethodInvocation) invocation).getMethod().getName();
+
+      if ("isClosed".equals(methodName))
+      {
+         return new Boolean(isClosed());
+      }
+
       boolean isClosing = methodName.equals("closing");
       boolean isClose = methodName.equals("close");
       
-//      if (trace) { log.trace(this + " invoking " + methodName + "()"); }
-
       if (isClosing)
       {         
          if (checkClosingAlreadyDone())
@@ -121,7 +158,18 @@
       }
       else
       {
-         inuse();
+         synchronized(this)
+         {
+            // object "in use", increment inUseCount
+            if (state == IN_CLOSE || state == CLOSED)
+            {
+               log.error(this + ": method " + methodName + "() did not go through, " +
+                                "the interceptor is " + stateToString(state));
+
+               throw new IllegalStateException("The object is closed");
+            }
+            ++inUseCount;
+         }
       }
 
       if (isClosing)
@@ -157,8 +205,7 @@
     * 
     * @return true when already closing or closed
     */
-   protected synchronized boolean checkClosingAlreadyDone()
-      throws Throwable
+   protected synchronized boolean checkClosingAlreadyDone() throws Throwable
    {
       if (state != NOT_CLOSED)
       {
@@ -171,8 +218,7 @@
    /**
     * Closing the object
     */
-   protected synchronized void closing()
-      throws Throwable
+   protected synchronized void closing() throws Throwable
    {
       state = CLOSING;
    }
@@ -183,14 +229,13 @@
     * 
     * @return true when already closed
     */
-   protected synchronized boolean checkCloseAlreadyDone()
-      throws Throwable
+   protected synchronized boolean checkCloseAlreadyDone() throws Throwable
    {
       if (state != CLOSING)
       {
          return true;
       }
-      while (inuseCount > 0)
+      while (inUseCount > 0)
       {
          wait();
       }
@@ -201,33 +246,18 @@
    /**
     * Closed the object
     */
-   protected synchronized void closed()
-      throws Throwable
+   protected synchronized void closed() throws Throwable
    {
       state = CLOSED;
-      if (trace) { log.trace("closed"); }
+      log.debug(this + " closed");
    }
    
    /**
-    * Mark the object as inuse
-    */
-   protected synchronized void inuse()
-      throws Throwable
-   {
-      if (state == IN_CLOSE || state == CLOSED)
-      {
-         throw new IllegalStateException("The object is closed");
-      }
-      ++inuseCount;
-   }
-   
-   /**
     * Mark the object as no longer inuse 
     */
-   protected synchronized void done()
-      throws Throwable
+   protected synchronized void done() throws Throwable
    {
-      if (--inuseCount == 0)
+      if (--inUseCount == 0)
       {
          notifyAll();
       }
@@ -242,8 +272,8 @@
    {                  
       HierarchicalState state = ((DelegateSupport)invocation.getTargetObject()).getState();
             
-      //We use a clone to avoid a deadlock where requests
-      //are made to close parent and child concurrently
+      // We use a clone to avoid a deadlock where requests are made to close parent and child
+      // concurrently
       
       Set clone;
 
@@ -251,7 +281,7 @@
       
       if (children == null)
       {
-         if (trace) { log.trace("No children"); }
+         if (trace) { log.trace(this + " has no children"); }
          return;
       }
       
@@ -260,8 +290,7 @@
          clone = new HashSet(children);
       }
       
-      // Cycle through the children this will do a depth
-      // first close
+      // Cycle through the children this will do a depth first close
       for (Iterator i = clone.iterator(); i.hasNext();)
       {
          HierarchicalState child = (HierarchicalState)i.next();      
@@ -290,7 +319,14 @@
 
    // Private --------------------------------------------------------
 
- 
+   private void getIdentity(Invocation i)
+   {
+      DelegateSupport ds = (DelegateSupport)i.getTargetObject();
+      id = new Integer(ds.getID());
+      delegateType = ds.getClass().getName();
+      delegateType = delegateType.substring(delegateType.lastIndexOf('.') + 1);
+   }
+
    // Inner Classes --------------------------------------------------
 
 }

Modified: trunk/src/main/org/jboss/jms/client/container/ConnectionAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ConnectionAspect.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/container/ConnectionAspect.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -104,7 +104,7 @@
       
       justCreated = false;
       
-      //This gets invoked on the server too
+      // this gets invoked on the server too
       return invocation.invokeNext();
    }
    
@@ -174,10 +174,10 @@
       state.getRemotingConnection().stop();
       
       // Remove reference to resource manager
-      ResourceManagerFactory.instance.returnResourceManager(state.getServerID());
+      ResourceManagerFactory.instance.checkInResourceManager(state.getServerID());
       
       // Remove reference to message id generator
-      MessageIdGeneratorFactory.instance.returnGenerator(state.getServerID());
+      MessageIdGeneratorFactory.instance.checkInGenerator(state.getServerID());
       
       return ret;
    }

Modified: trunk/src/main/org/jboss/jms/client/container/ProducerAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ProducerAspect.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/container/ProducerAspect.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -97,7 +97,7 @@
 
       if (deliveryMode == -1)
       {
-         //Use the delivery mode of the producer
+         // Use the delivery mode of the producer
          deliveryMode = producerState.getDeliveryMode();
          if (trace) { log.trace("Using producer's default delivery mode: " + deliveryMode); }
       }
@@ -105,7 +105,7 @@
 
       if (priority == -1)
       {
-         //Use the priority of the producer
+         // Use the priority of the producer
          priority = producerState.getPriority();
          if (trace) { log.trace("Using producer's default priority: " + priority); }
       }

Modified: trunk/src/main/org/jboss/jms/client/container/SessionAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/SessionAspect.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/container/SessionAspect.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -23,9 +23,12 @@
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
 
 import javax.jms.IllegalStateException;
 import javax.jms.Session;
+import javax.jms.JMSException;
 
 import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.aop.joinpoint.MethodInvocation;
@@ -44,6 +47,7 @@
  * This aspect is PER_VM
  *
  * @author <a href="mailto:tim.fox at jboss.com>Tim Fox</a>
+ * @author <a href="mailto:ovidiu at jboss.com>Ovidiu Feodorov</a>
  *
  * $Id$
  */
@@ -63,42 +67,52 @@
    
    // Public --------------------------------------------------------
 
+   public Object handleClosing(Invocation invocation) throws Throwable
+   {
+      // Send to the server all acknowledgments accumulated in toAck. This is useful, for example,
+      // when a message listener close the session from its onMessage().
+      acknowledgeOnClosing(invocation);
+
+      return invocation.invokeNext();
+   }
+
+
    public Object handleClose(Invocation invocation) throws Throwable
    {      
       Object res = invocation.invokeNext();
-      
+
+      // We must explicitly shutdown the executor
+
       SessionState state = getState(invocation);
-      
-      //We must explicitly shutdown the executor
+      state.getExecutor().shutdownNow();
 
-      state.getExecutor().shutdownNow();
-         
       return res;
-   }      
+   }
    
    public Object handlePreDeliver(Invocation invocation) throws Throwable
    { 
       MethodInvocation mi = (MethodInvocation)invocation;
-      
       SessionState state = getState(invocation);
       
       int ackMode = state.getAcknowledgeMode();
       
-      if (ackMode == Session.CLIENT_ACKNOWLEDGE || ackMode == Session.AUTO_ACKNOWLEDGE ||
-          ackMode == Session.DUPS_OK_ACKNOWLEDGE)
+      if (ackMode == Session.CLIENT_ACKNOWLEDGE ||
+          ackMode == Session.AUTO_ACKNOWLEDGE ||
+          ackMode == Session.DUPS_OK_ACKNOWLEDGE ||
+          state.getCurrentTxId() == null)
       {
+         // We collect acknowledgments (and not transact them) for CLIENT, AUTO and DUPS_OK, and
+         // also for XA sessions not enrolled in a global transaction.
+
          SessionDelegate del = (SessionDelegate)mi.getTargetObject();
          
-         //We store the ack in a list for later acknowledgement or recovery
+         // We store the ack in a list for later acknowledgement or recovery
     
          Object[] args = mi.getArguments();
-         
          MessageProxy mp = (MessageProxy)args[0];
-         
          int consumerID = ((Integer)args[1]).intValue();
+         AckInfo info = new AckInfo(mp, consumerID, ackMode);
          
-         AckInfo info = new AckInfo(mp, consumerID);
-         
          state.getToAck().add(info);
          
          if (trace) { log.trace("ack mode is " + Util.acknowledgmentModeToString(ackMode)+ ", acknowledged on " + del); }
@@ -110,9 +124,7 @@
    public Object handleAcknowledgeAll(Invocation invocation) throws Throwable
    {    
       MethodInvocation mi = (MethodInvocation)invocation;
-      
       SessionState state = getState(invocation);
-      
       SessionDelegate del = (SessionDelegate)mi.getTargetObject();
     
       if (!state.getToAck().isEmpty())
@@ -128,42 +140,34 @@
    public Object handlePostDeliver(Invocation invocation) throws Throwable
    { 
       MethodInvocation mi = (MethodInvocation)invocation;
-      
       SessionState state = getState(invocation);
       
       int ackMode = state.getAcknowledgeMode();
       
-      if (ackMode == Session.AUTO_ACKNOWLEDGE || ackMode == Session.DUPS_OK_ACKNOWLEDGE)
+      if (ackMode == Session.AUTO_ACKNOWLEDGE ||
+          ackMode == Session.DUPS_OK_ACKNOWLEDGE ||
+          ackMode != Session.CLIENT_ACKNOWLEDGE && state.getCurrentTxId() == null)
       {
-         SessionDelegate del = (SessionDelegate)mi.getTargetObject();
-         
-         //We acknowledge immediately
-         
+         // We acknowledge immediately on a non-transacted session that does not want to
+         // CLIENT_ACKNOWLEDGE, or an XA session not enrolled in a global transaction.
+
+         SessionDelegate sd = (SessionDelegate)mi.getTargetObject();
+
          if (!state.isRecoverCalled())
          {
-            //We don't acknowledge the message if recover() was called
-            
-            //Object[] args = mi.getArguments();
-            
-            //MessageProxy proxy = (MessageProxy)args[0];
-                   
-            //int consumerID = ((Integer)args[1]).intValue();
+            if (trace) { log.trace("acknowledging NON-transactionally"); }
 
-            //AckInfo ack = new AckInfo(proxy, consumerID);
-            
             List acks = state.getToAck();
-            
             AckInfo ack = (AckInfo)acks.get(0);
-            
-            del.acknowledge(ack);   
-               
-            state.getToAck().clear();            
+            sd.acknowledge(ack);
+            state.getToAck().clear();
          }
          else
          {
+            if (trace) { log.trace("recover called, so NOT acknowledging"); }
+
             state.setRecoverCalled(false);
          }
-         if (trace) { log.trace("ack mode is " + Util.acknowledgmentModeToString(ackMode)+ ", acknowledged on " + del); }
       }
 
       return null;
@@ -302,6 +306,35 @@
    {
       return (SessionState)((DelegateSupport)inv.getTargetObject()).getState();
    }
+
+   /**
+    * The method sends to server all eligible acknowlegments (those that are NOT CLIIENT_ACKNOWLEDGE
+    * for example)
+    */
+   private void acknowledgeOnClosing(Invocation invocation) throws JMSException
+   {
+      MethodInvocation mi = (MethodInvocation)invocation;
+      SessionState state = getState(invocation);
+      SessionDelegate del = (SessionDelegate)mi.getTargetObject();
+
+      // select eligible acknowledgments
+      List acks = new ArrayList();
+      for(Iterator i = state.getToAck().iterator(); i.hasNext(); )
+      {
+         AckInfo ack = (AckInfo)i.next();
+         if (ack.getAckMode() == Session.AUTO_ACKNOWLEDGE ||
+             ack.getAckMode() == Session.DUPS_OK_ACKNOWLEDGE)
+         {
+            acks.add(ack);
+            i.remove();
+         }
+      }
+
+      if (!acks.isEmpty())
+      {
+         del.acknowledgeBatch(acks);
+      }
+   }
     
    // Inner Classes -------------------------------------------------
    

Modified: trunk/src/main/org/jboss/jms/client/container/StateCreationAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/StateCreationAspect.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/container/StateCreationAspect.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -83,9 +83,9 @@
 
       String serverID = cfd.getServerID();
 
-      ResourceManager rm = ResourceManagerFactory.instance.getResourceManager(serverID);
+      ResourceManager rm = ResourceManagerFactory.instance.checkOutResourceManager(serverID);
       MessageIdGenerator gen =
-         MessageIdGeneratorFactory.instance.getGenerator(serverID, cfd);
+         MessageIdGeneratorFactory.instance.checkOutGenerator(serverID, cfd);
 
       ConnectionState connectionState =
          new ConnectionState(serverID, connectionDelegate,

Modified: trunk/src/main/org/jboss/jms/client/container/TransactionAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/TransactionAspect.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/container/TransactionAspect.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -24,6 +24,7 @@
 import javax.jms.IllegalStateException;
 import javax.jms.Message;
 import javax.jms.TransactionInProgressException;
+import javax.jms.Session;
 
 import org.jboss.aop.joinpoint.Invocation;
 import org.jboss.aop.joinpoint.MethodInvocation;
@@ -36,8 +37,7 @@
 import org.jboss.jms.tx.AckInfo;
 import org.jboss.jms.tx.LocalTx;
 import org.jboss.jms.tx.ResourceManager;
-import org.jboss.jms.tx.TxState;
-import org.jboss.jms.util.MessagingTransactionRolledBackException;
+import org.jboss.logging.Logger;
 
 /**
  * This aspect handles transaction related logic
@@ -45,6 +45,7 @@
  * This aspect is PER_VM.
  * 
  * @author <a href="mailto:tim.fox at jboss.com>Tim Fox</a>
+ * @author <a href="mailto:ovidiu at jboss.com>Ovidiu Feodorov</a>
  *
  * $Id$
  */
@@ -52,8 +53,12 @@
 {
    // Constants -----------------------------------------------------
 
+   private static final Logger log = Logger.getLogger(TransactionAspect.class);
+
    // Attributes ----------------------------------------------------
 
+   private boolean trace = log.isTraceEnabled();
+
    // Static --------------------------------------------------------
 
    // Constructors --------------------------------------------------
@@ -129,13 +134,6 @@
       ResourceManager rm = connState.getResourceManager();
       ConnectionDelegate conn = (ConnectionDelegate)connState.getDelegate();
 
-      TxState tx = rm.getTx(state.getCurrentTxId());
-
-      if (tx == null)
-      {
-         throw new IllegalStateException("Cannot find tx:" + state.getCurrentTxId());
-      }
-
       try
       {
          rm.rollbackLocal((LocalTx)state.getCurrentTxId(), conn);
@@ -152,62 +150,50 @@
 
    public Object handleSend(Invocation invocation) throws Throwable
    {
-      SessionState sessionState = (SessionState)getState(invocation);
+      SessionState state = (SessionState)getState(invocation);
+      Object txID = state.getCurrentTxId();
 
-      if (sessionState.isTransacted())
+      if (txID != null)
       {
-         //Session is transacted - so we add message to tx instead of sending now
+         // the session is non-XA and transacted, or XA and enrolled in a global transaction, so
+         // we add the message to a transaction instead of sending it now. An XA session that has
+         // not been enrolled in a global transaction behaves as a non-transacted session.
 
-         Object txID = sessionState.getCurrentTxId();
-
-         if (txID == null)
-         {
-            throw new IllegalStateException("Attempt to send message in tx, but txId is null, XA?" + sessionState.isXA());
-         }
-
-         ConnectionState connState = (ConnectionState)sessionState.getParent();
-
+         ConnectionState connState = (ConnectionState)state.getParent();
          MethodInvocation mi = (MethodInvocation)invocation;
-
          Message m = (Message)mi.getArguments()[0];
 
+         if (trace) { log.trace("sending message " + m + " transactionally, queueing on resource manager"); }
+
          connState.getResourceManager().addMessage(txID, m);
 
          // ... and we don't invoke any further interceptors in the stack
          return null;
       }
-      else
-      {
-         return invocation.invokeNext();
-      }
+
+      if (trace) { log.trace("sending message NON-transactionally"); }
+
+      return invocation.invokeNext();
    }
 
    public Object handlePreDeliver(Invocation invocation) throws Throwable
    {
       SessionState state = (SessionState)getState(invocation);
+      Object txID = state.getCurrentTxId();
 
-      if (state.isTransacted())
+      if (txID != null)
       {
-         MethodInvocation mi = (MethodInvocation)invocation;
+         // the session is non-XA and transacted, or XA and enrolled in a global transaction. An
+         // XA session that has not been enrolled in a global transaction behaves as a
+         // non-transacted session.
 
+         MethodInvocation mi = (MethodInvocation)invocation;
          MessageProxy proxy = (MessageProxy)mi.getArguments()[0];
-
-         //long messageID = proxy.getMessage().getMessageID();
-
          int consumerID = ((Integer)mi.getArguments()[1]).intValue();
-
-         AckInfo info = new AckInfo(proxy, consumerID);
-
-         Object txID = state.getCurrentTxId();
-
-         if (txID == null)
-         {
-            throw new IllegalStateException("Attempt to send message in tx, but txId is null, XA?" + state.isXA());
-         }
-
+         AckInfo info = new AckInfo(proxy, consumerID, Session.SESSION_TRANSACTED);
          ConnectionState connState = (ConnectionState)state.getParent();
 
-         //Add the acknowledgement to the transaction
+         if (trace) { log.trace("sending acknowlegment transactionally, queueing on resource manager"); }
 
          connState.getResourceManager().addAck(txID, info);
       }

Modified: trunk/src/main/org/jboss/jms/client/delegate/ClientBrowserDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/ClientBrowserDelegate.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/delegate/ClientBrowserDelegate.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -60,7 +60,6 @@
       
    }
 
-
    // BrowserDelegate implementation --------------------------------
 
    /**
@@ -77,6 +76,11 @@
       throw new IllegalStateException("This invocation should not be handled here!");
    }
 
+   public boolean isClosed()
+   {
+      throw new IllegalStateException("This invocation should not be handled here!");
+   }
+
    public boolean hasNextMessage() throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");

Modified: trunk/src/main/org/jboss/jms/client/delegate/ClientConnectionDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/ClientConnectionDelegate.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/delegate/ClientConnectionDelegate.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -93,6 +93,15 @@
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
+   public boolean isClosed()
+   {
+      throw new IllegalStateException("This invocation should not be handled here!");
+   }
+
+   /**
+    * This invocation should either be handled by the client-side interceptor chain or by the
+    * server-side endpoint.
+    */
    public JBossConnectionConsumer createConnectionConsumer(Destination dest,
                                                            String subscriptionName,
                                                            String messageSelector,

Modified: trunk/src/main/org/jboss/jms/client/delegate/ClientConnectionFactoryDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/ClientConnectionFactoryDelegate.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/delegate/ClientConnectionFactoryDelegate.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -212,7 +212,7 @@
                remotingConnection.stop();
             }
             catch (Throwable ignore)
-            {               
+            {
             }
          }
          

Modified: trunk/src/main/org/jboss/jms/client/delegate/ClientConsumerDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/ClientConsumerDelegate.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/delegate/ClientConsumerDelegate.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -59,7 +59,6 @@
    public ClientConsumerDelegate(int objectID, int bufferSize)
    {
       super(objectID);
-      
       this.bufferSize = bufferSize;
    }
    
@@ -100,6 +99,15 @@
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
+   public boolean isClosed()
+   {
+      throw new IllegalStateException("This invocation should not be handled here!");
+   }
+
+   /**
+    * This invocation should either be handled by the client-side interceptor chain or by the
+    * server-side endpoint.
+    */
    public MessageListener getMessageListener()
    {
       throw new IllegalStateException("This invocation should not be handled here!");

Modified: trunk/src/main/org/jboss/jms/client/delegate/ClientProducerDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/ClientProducerDelegate.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/delegate/ClientProducerDelegate.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -55,7 +55,6 @@
    {
       super(-1);
    }
-   
 
    // ProducerDelegate implementation -------------------------------
 
@@ -81,6 +80,15 @@
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
+   public boolean isClosed()
+   {
+      throw new IllegalStateException("This invocation should not be handled here!");
+   }
+
+   /**
+    * This invocation should either be handled by the client-side interceptor chain or by the
+    * server-side endpoint.
+    */
    public int getDeliveryMode() throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");

Modified: trunk/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/delegate/ClientSessionDelegate.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -83,25 +83,25 @@
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
-   public void acknowledge(AckInfo ackInfo) throws JMSException
+   public void close() throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }
-   
+
    /**
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
-   public void acknowledgeBatch(List ackInfos) throws JMSException
+   public void closing() throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }
-   
+
    /**
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
-   public void acknowledgeAll() throws JMSException
+   public boolean isClosed()
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }
@@ -110,25 +110,34 @@
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
-   public void addTemporaryDestination(JBossDestination destination) throws JMSException
+   public void acknowledge(AckInfo ackInfo) throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }
-
+   
    /**
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
-   public void redeliver() throws JMSException
+   public void acknowledgeBatch(List ackInfos) throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }
+   
+   /**
+    * This invocation should either be handled by the client-side interceptor chain or by the
+    * server-side endpoint.
+    */
+   public void acknowledgeAll() throws JMSException
+   {
+      throw new IllegalStateException("This invocation should not be handled here!");
+   }
 
    /**
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
-   public void close() throws JMSException
+   public void addTemporaryDestination(JBossDestination destination) throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }
@@ -137,7 +146,7 @@
     * This invocation should either be handled by the client-side interceptor chain or by the
     * server-side endpoint.
     */
-   public void closing() throws JMSException
+   public void redeliver() throws JMSException
    {
       throw new IllegalStateException("This invocation should not be handled here!");
    }

Modified: trunk/src/main/org/jboss/jms/client/delegate/DelegateSupport.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/delegate/DelegateSupport.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/delegate/DelegateSupport.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -78,7 +78,6 @@
    public DelegateSupport(int objectID)
    {
       this.id = objectID;    
-      
       trace = log.isTraceEnabled();
    }
    

Modified: trunk/src/main/org/jboss/jms/client/remoting/CallbackServerFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/remoting/CallbackServerFactory.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/remoting/CallbackServerFactory.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -33,90 +33,116 @@
 import org.jboss.remoting.transport.PortUtil;
 
 /**
- * 
+ *
  * A CallbackServerFactory.
- * 
+ *
  * We maintain only one callbackserver per transport per client VM.
  * This is to avoid having too many resources e.g. server sockets in use on the client
  * E.g. in the case of a socket transport, if we had one callbackserver per connection then
  * we would have one server socket listening per connection, so we could run out of available
  * ports with a lot of connections.
- * 
+ *
  * @author <a href="tim.fox at jboss.com">Tim Fox</a>
  * @version $Revision$
  *
  * $Id$
  */
 public class CallbackServerFactory
-{      
+{
    private static final Logger log = Logger.getLogger(CallbackServerFactory.class);
-   
+
    private static final String CALLBACK_SERVER_PARAMS =
       "/?marshaller=org.jboss.jms.server.remoting.JMSWireFormat&" +
       "unmarshaller=org.jboss.jms.server.remoting.JMSWireFormat&" +
       "dataType=jms&" +
       "timeout=0&" +
       "socket.check_connection=false";
-   
+
    public static final String JMS_CALLBACK_SUBSYSTEM = "CALLBACK";
+
+   public static final String CLIENT_HOST =
+      System.getProperty("jboss.messaging.callback.bind.address");
    
-   public static final String CLIENT_HOST = System.getProperty("jboss.messaging.callback.bind.address");
+   public static final int CLIENT_PORT = getPort();
    
+   private static int getPort()
+   {
+	   String propertyPort = System.getProperty("jboss.messaging.callback.bind.port");
+	   
+	   try
+	   {
+		   if (propertyPort!=null)
+		   {
+			   return Integer.parseInt(propertyPort);
+		   }
+		   else
+		   {
+			   return -1;
+		   }
+	   }
+	   catch (Exception e)
+	   {
+		   log.warn("Error during parsing jboss.messaging.callback.bind.port", e);
+		   return -1;
+	   }
+	   
+   }
+
    public static CallbackServerFactory instance = new CallbackServerFactory();
-   
+
    private Map holders;
-   
+
    private CallbackServerFactory()
-   {      
+   {
       holders = new HashMap();
    }
-      
+
    public synchronized boolean containsCallbackServer(String protocol)
    {
       return holders.containsKey(protocol);
    }
-   
+
    public synchronized Connector getCallbackServer(InvokerLocator serverLocator) throws Exception
    {
       String protocol = serverLocator.getProtocol();
-      
-      Holder h = (Holder)holders.get(protocol);           
-      
+
+      Holder h = (Holder)holders.get(protocol);
+
       if (h == null)
-      {         
+      {
          h = new Holder();
-         
+
          h.server = startCallbackServer(serverLocator);
-         
+
          holders.put(protocol, h);
       }
       else
       {
          h.refCount++;
       }
-      
+
       return h.server;
    }
-   
+
    public synchronized void stopCallbackServer(String protocol)
    {
       Holder h = (Holder)holders.get(protocol);
-      
+
       if (h == null)
       {
          throw new IllegalArgumentException("Cannot find callback server for protocol: " + protocol);
       }
-      
+
       h.refCount--;
-      
+
       if (h.refCount == 0)
       {
          stopCallbackServer(h.server);
-         
+
          holders.remove(protocol);
-      }      
+      }
    }
-   
+
    protected Connector startCallbackServer(InvokerLocator serverLocator) throws Exception
    {
       if (log.isTraceEnabled()) { log.trace(this + " setting up connection to " + serverLocator); }
@@ -149,8 +175,12 @@
       {
          try
          {      
-            int bindPort = PortUtil.findFreePort(thisAddress);
-      
+            int bindPort = CLIENT_PORT;
+            if (bindPort<=0)
+            {
+            	bindPort=PortUtil.findFreePort(thisAddress);
+            }
+            
             String callbackServerURI;
       
             if (isSSL)

Modified: trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -64,11 +64,10 @@
       trace = log.isTraceEnabled();
    }
      
-   //Hardcoded for now
+   // Hardcoded for now
    private static final int MAX_REDELIVERIES = 10;
       
-   public static void callOnMessage(ConsumerDelegate cons,
-                                    SessionDelegate sess,
+   public static void callOnMessage(SessionDelegate sess,
                                     MessageListener listener,
                                     int consumerID,
                                     boolean isConnectionConsumer,
@@ -76,15 +75,19 @@
                                     int ackMode)
       throws JMSException
    {
-      preDeliver(sess, consumerID, m, isConnectionConsumer);  
+      preDeliver(sess, consumerID, m, isConnectionConsumer);
                   
       int tries = 0;
       
       while (true)
       {
          try
-         {      
-            listener.onMessage(m); 
+         {
+            if (trace) { log.trace("calling listener's onMessage(" + m + ")"); }
+
+            listener.onMessage(m);
+
+            if (trace) { log.trace("listener's onMessage() finished"); }
             
             break;
          }
@@ -103,9 +106,9 @@
                {
                   m.setJMSRedelivered(true);
                   
-                  //TODO delivery count although optional should be global
-                  //so we need to send it back to the server
-                  //but this has performance hit so perhaps we just don't support it?
+                  // TODO delivery count although optional should be global so we need to send it
+                  // back to the server but this has performance hit so perhaps we just don't
+                  // support it?
                   m.incDeliveryCount();
                   
                   tries++;
@@ -129,8 +132,12 @@
             }
          }
       }
-            
-      postDeliver(sess, consumerID, m, isConnectionConsumer);          
+
+      if (!sess.isClosed())
+      {
+         // postDeliver only if the session is not closed
+         postDeliver(sess, isConnectionConsumer);
+      }
    }
    
    protected static void preDeliver(SessionDelegate sess,
@@ -147,10 +154,7 @@
       }         
    }
    
-   protected static void postDeliver(SessionDelegate sess,
-                                     int consumerID,
-                                     MessageProxy m,
-                                     boolean isConnectionConsumer)
+   protected static void postDeliver(SessionDelegate sess, boolean isConnectionConsumer)
       throws JMSException
    {
       // If this is the callback-handler for a connection consumer we don't want to acknowledge or
@@ -203,15 +207,15 @@
       }
               
       this.bufferSize = bufferSize;
-      
+
       buffer = new LinkedList();
-      
+
       isConnectionConsumer = isCC;
       
       this.ackMode = ackMode;
-      
+
       this.sessionDelegate = sess;
-      
+
       this.consumerDelegate = cons;
       
       this.consumerID = consumerID;
@@ -302,13 +306,13 @@
          
          if (receiverThread != null)
          {            
-            //Wake up any receive() thread that might be waiting
+            // Wake up any receive() thread that might be waiting
             mainLock.notify();
          }   
          
          this.listener = null;
       }
-         
+
       waitForOnMessageToComplete();
       
       // Now we cancel anything left in the buffer. The reason we do this now is that otherwise the
@@ -342,15 +346,25 @@
    
    private void waitForOnMessageToComplete()
    {
-      // Wait for any on message executions to complete
-      
+      // Wait for any onMessage() executions to complete
+
+      if (Thread.currentThread().equals(sessionExecutor.getThread()))
+      {
+         // the current thread already closing this MessageCallbackHandler (this happens when the
+         // session is closed from within the MessageListener.onMessage(), for example), so no need
+         // to register another Closer (see http://jira.jboss.org/jira/browse/JBMESSAGING-542)
+         return;
+      }
+
       Future result = new Future();
       
       try
       {
-         this.sessionExecutor.execute(new Closer(result));
-         
+         sessionExecutor.execute(new Closer(result));
+
+         if (trace) { log.trace("blocking wait for Closer execution"); }
          result.getResult();
+         if (trace) { log.trace("got Closer result"); }
       }
       catch (InterruptedException e)
       {
@@ -439,7 +453,7 @@
                // message is acknowledged so it gets removed from the queue/subscription.
                preDeliver(sessionDelegate, consumerID, m, isConnectionConsumer);
                
-               postDeliver(sessionDelegate, consumerID, m, isConnectionConsumer);
+               postDeliver(sessionDelegate, isConnectionConsumer);
                
                if (!m.getMessage().isExpired())
                {
@@ -590,9 +604,9 @@
       {         
          MessageProxy msg = (MessageProxy)iter.next();
       
-         //if this is the handler for a connection consumer we don't want to set the session delegate
-         //since this is only used for client acknowledgement which is illegal for a session
-         //used for an MDB
+         // If this is the handler for a connection consumer we don't want to set the session
+         // delegate since this is only used for client acknowledgement which is illegal for a
+         // session used for an MDB
          msg.setSessionDelegate(sessionDelegate, isConnectionConsumer);
                   
          msg.setReceived();
@@ -628,7 +642,7 @@
          {
             listenerRunning = true;
 
-            if (trace) { log.trace(this + ": new ListenerRunner scheduled"); }
+            if (trace) { log.trace(this + " scheduled a new ListenerRunner"); }
             this.queueRunner(new ListenerRunner());
          }     
          
@@ -653,7 +667,11 @@
       
       public void run()
       {
+         if (trace) { log.trace("Closer starts running"); }
+
          result.setResult(null);
+
+         if (trace) { log.trace("Closer finished run"); }
       }
    }
    
@@ -673,15 +691,16 @@
             if (listener == null)
             {
                listenerRunning = false;
-               
+               if (trace) { log.trace("no listener, returning"); }
                return;
             }
             
-            //remove a message from the buffer
+            // remove a message from the buffer
 
             if (buffer.isEmpty())
             {
-               listenerRunning = false;               
+               listenerRunning = false;
+               if (trace) { log.trace("no messages in buffer, marking listener as not running"); }
             }
             else
             {               
@@ -697,6 +716,7 @@
                if (!again)
                {
                   listenerRunning  = false;
+                  if (trace) { log.trace("no more messages in buffer, marking listener as not running"); }
                }  
             }
          }
@@ -705,7 +725,7 @@
          {
             try
             {
-               callOnMessage(consumerDelegate, sessionDelegate, listener, consumerID, false, mp, ackMode);
+               callOnMessage(sessionDelegate, listener, consumerID, false, mp, ackMode);
             }
             catch (JMSException e)
             {
@@ -715,14 +735,14 @@
          
          if (again)
          {
-            //Queue it up again
+            // Queue it up again
             queueRunner(this);
          }
          else
          {
             if (!serverSending)
             {
-               //Ask server for more messages
+               // Ask server for more messages
                try
                {
                   consumerDelegate.more();

Modified: trunk/src/main/org/jboss/jms/client/state/SessionState.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/state/SessionState.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/client/state/SessionState.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -27,8 +27,6 @@
 import java.util.List;
 import java.util.Map;
 
-import javax.jms.Session;
-
 import org.jboss.jms.client.remoting.MessageCallbackHandler;
 import org.jboss.jms.delegate.SessionDelegate;
 import org.jboss.jms.server.Version;
@@ -57,11 +55,12 @@
    
    private Object currentTxId;
    
-   //Executor used for executing onMessage methods
+   // Executor used for executing onMessage methods
    private QueuedExecutor executor;
    
    private boolean recoverCalled;
-   
+
+   // List<AckInfo>
    private List toAck;
    
    private Map callbackHandlers;
@@ -73,30 +72,35 @@
       children = new HashSet();
       this.acknowledgeMode = ackMode;
       this.transacted = transacted;
-      this.xa = xa;      
+      this.xa = xa;
+
       if (xa)
       {
-         //Create an XA resource
+         // Create an XA resource
          xaResource = new MessagingXAResource(parent.getResourceManager(), this);                            
       }
-      if (transacted)
+
+      // If session is transacted and XA, the currentTxId will be updated when the XAResource will
+      // be enrolled with a global transaction.
+
+      if (transacted & !xa)
       {
-         //Create a local tx                                                  
+         // Create a local tx
          currentTxId = parent.getResourceManager().createLocalTx();        
       }
+
       executor = new QueuedExecutor(new LinkedQueue());
       
-      if (ackMode == Session.CLIENT_ACKNOWLEDGE || ackMode == Session.AUTO_ACKNOWLEDGE ||
-          ackMode == Session.DUPS_OK_ACKNOWLEDGE)
-      {
-         toAck = new ArrayList();
-      }
-      
-      //TODO could optimise this to use the same map of callbackmanagers (which holds refs
-      //to callbackhandlers) in the connection, instead of maintaining another map
+      toAck = new ArrayList();
+
+      // TODO could optimise this to use the same map of callbackmanagers (which holds refs
+      // to callbackhandlers) in the connection, instead of maintaining another map
       callbackHandlers = new HashMap();
    }
-   
+
+   /**
+    * @return List<AckInfo>
+    */
    public List getToAck()
    {
       return toAck;

Modified: trunk/src/main/org/jboss/jms/delegate/SessionDelegate.java
===================================================================
--- trunk/src/main/org/jboss/jms/delegate/SessionDelegate.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/delegate/SessionDelegate.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -79,9 +79,9 @@
    
    void addAsfMessage(MessageProxy m, int consumerID, ConsumerDelegate cons);
    
-   public boolean getTransacted();
+   boolean getTransacted();
    
-   public int getAcknowledgeMode();   
+   int getAcknowledgeMode();
    
    void commit() throws JMSException;
    

Modified: trunk/src/main/org/jboss/jms/message/JBossMessage.java
===================================================================
--- trunk/src/main/org/jboss/jms/message/JBossMessage.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/message/JBossMessage.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -79,13 +79,9 @@
    private static final byte NULL = 0;
    
    private static final byte STRING = 1;
-   
    private static final byte BYTES = 2;
-   
    private static final byte QUEUE = 3;
-   
    private static final byte TOPIC = 4;
-   
    private static final byte TEMP_QUEUE = 5;
    
    private static final byte TEMP_TOPIC = 6;

Modified: trunk/src/main/org/jboss/jms/message/MessageIdGeneratorFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/message/MessageIdGeneratorFactory.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/message/MessageIdGeneratorFactory.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -27,6 +27,7 @@
 import javax.jms.JMSException;
 
 import org.jboss.jms.delegate.ConnectionFactoryDelegate;
+import org.jboss.logging.Logger;
 
 /**
  * This class manages instances of MessageIdGenerator. It ensures there is one instance per instance
@@ -39,25 +40,37 @@
  */
 public class MessageIdGeneratorFactory
 {
+   // Constants -----------------------------------------------------
+
+   private static final Logger log = Logger.getLogger(MessageIdGeneratorFactory.class);
+
    public static MessageIdGeneratorFactory instance = new MessageIdGeneratorFactory();
 
    //TODO Make configurable
    private static final int BLOCK_SIZE = 256;
 
+   // Static --------------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
    private Map holders;
 
+   // Constructors --------------------------------------------------
+
    private MessageIdGeneratorFactory()
    {
       holders = new HashMap();
    }
 
+   // Public --------------------------------------------------------
+
    public synchronized boolean containsMessageIdGenerator(String serverId)
    {
       return holders.containsKey(serverId);
    }
 
-   public synchronized MessageIdGenerator getGenerator(String serverId,
-                                                       ConnectionFactoryDelegate cfd)
+   public synchronized MessageIdGenerator checkOutGenerator(String serverId,
+                                                            ConnectionFactoryDelegate cfd)
       throws JMSException
    {
       Holder h = (Holder)holders.get(serverId);
@@ -65,17 +78,21 @@
       if (h == null)
       {
          h = new Holder(new MessageIdGenerator(cfd, BLOCK_SIZE));
-
          holders.put(serverId, h);
       }
       else
       {
          h.refCount++;
       }
+
+      log.debug("checked out MessageIdGenerator for " + serverId +
+                ", reference count is " + h.refCount);
+
+
       return h.generator;
    }
 
-   public synchronized void returnGenerator(String serverId)
+   public synchronized void checkInGenerator(String serverId)
    {
       Holder h = (Holder)holders.get(serverId);
 
@@ -89,14 +106,29 @@
       if (h.refCount == 0)
       {
          holders.remove(serverId);
+         log.debug("checked in and removed MessageIdGenerator for " + serverId);
       }
+      else
+      {
+         log.debug("checked in MessageIdGenerator for " + serverId +
+                   ", reference count is " + h.refCount);
+      }
    }
 
    public synchronized void clear()
    {
       holders.clear();
+      log.debug("cleared MessageIdGeneratorFactory");
    }
 
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
    private class Holder
    {
       private Holder(MessageIdGenerator gen)

Modified: trunk/src/main/org/jboss/jms/message/MessageProxy.java
===================================================================
--- trunk/src/main/org/jboss/jms/message/MessageProxy.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/message/MessageProxy.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -59,6 +59,10 @@
    
    // Static --------------------------------------------------------
 
+   protected static final int STATE_NEW = 0;
+   protected static final int STATE_SENT = 1;
+   protected static final int STATE_RECEIVED = 2;
+
    // Attributes ----------------------------------------------------
 
    protected JBossMessage message;
@@ -66,27 +70,16 @@
    protected transient SessionDelegate delegate;
    
    protected transient boolean cc;
-
    protected transient boolean messageCopied;
-
    protected transient boolean propertiesCopied;
-
    protected transient boolean bodyCopied;
 
    protected transient int state;
 
-   protected static final int STATE_NEW = 0;
-
-   protected static final int STATE_SENT = 1;
-
-   protected static final int STATE_RECEIVED = 2;
-
    protected transient boolean propertiesReadOnly;
-
    protected transient boolean bodyReadOnly;
 
    protected int deliveryCount;
-
    protected transient boolean jmsRedelivered;
 
    // Constructors --------------------------------------------------
@@ -264,6 +257,10 @@
 
    public long getLongProperty(String name) throws JMSException
    {
+      if ("JMSXDeliveryCount".equals(name))
+      {
+         return deliveryCount;
+      }
       return message.getLongProperty(name);
    }
 
@@ -279,6 +276,10 @@
 
    public String getStringProperty(String name) throws JMSException
    {
+      if ("JMSXDeliveryCount".equals(name))
+      {
+         return Integer.toString(deliveryCount);
+      }
       return message.getStringProperty(name);
    }
 
@@ -407,7 +408,7 @@
 
       bodyReadOnly = true;
 
-      this.jmsRedelivered = deliveryCount > 0;
+      this.jmsRedelivered = deliveryCount > 1;
    }
 
    public JBossMessage getMessage()

Modified: trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -86,12 +86,12 @@
       ServerConnectionFactoryEndpoint endpoint =
          new ServerConnectionFactoryEndpoint(id, serverPeer, clientID, jndiBindings,
                                              prefetchSize, defaultTempQueueFullSize,
-                                             defaultTempQueuePageSize, defaultTempQueueDownCacheSize);
+                                             defaultTempQueuePageSize,
+                                             defaultTempQueueDownCacheSize);
 
-      ClientConnectionFactoryDelegate delegate = new ClientConnectionFactoryDelegate(id, locatorURI,
-                                                                                      serverPeer.getVersion(),
-                                                                                      serverPeer.getServerPeerID(),
-                                                                                      clientPing);
+      ClientConnectionFactoryDelegate delegate =
+         new ClientConnectionFactoryDelegate(id, locatorURI, serverPeer.getVersion(),
+                                             serverPeer.getServerPeerID(), clientPing);
 
       ConnectionFactoryAdvised connFactoryAdvised = new ConnectionFactoryAdvised(endpoint);
       

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerBrowserEndpoint.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -152,9 +152,14 @@
    
    public void closing() throws JMSException
    {
-      //Do nothing
+      // Do nothing
    }
 
+   public boolean isClosed()
+   {
+      return closed;
+   }
+
    // Public --------------------------------------------------------
 
    public String toString()

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -47,8 +47,6 @@
 import org.jboss.jms.tx.TransactionRequest;
 import org.jboss.jms.tx.TxState;
 import org.jboss.jms.util.ExceptionUtil;
-import org.jboss.jms.util.MessagingJMSException;
-import org.jboss.jms.util.MessagingTransactionRolledBackException;
 import org.jboss.jms.util.ToString;
 import org.jboss.logging.Logger;
 import org.jboss.messaging.core.MessageReference;
@@ -279,7 +277,7 @@
    {      
       try
       {
-         if (trace) { log.trace("close()"); }
+         if (trace) { log.trace(this + " close()"); }
          
          if (closed)
          {
@@ -334,9 +332,14 @@
    
    public void closing() throws JMSException
    {
-      log.trace("closing (noop)");    
+      log.trace(this + " closing (noop)");    
    }
-     
+
+   public boolean isClosed()
+   {
+      return closed;
+   }
+
    public void sendTransaction(TransactionRequest request) throws JMSException
    {    
       try

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -132,9 +132,7 @@
          
          log.debug("created and registered " + endpoint);
    
-         ClientConnectionDelegate delegate = new ClientConnectionDelegate(connectionID);     
-         
-         return delegate;
+         return new ClientConnectionDelegate(connectionID);
       }
       catch (Throwable t)
       {

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -224,12 +224,20 @@
          // queue for delivery later.
          if (!started)
          {
-            // this is a common programming error, make this visible in the debug logs
-            // TODO: analyse performance implications
-            log.debug(this + " NOT started yet!");
+            // this is a common programming error, make this visible in the debug logs. However,
+            // make also possible to cut out the performance overhead for systems that raise the
+            // threshold to INFO or higher.
+
+            if (log.isDebugEnabled())
+            {
+               log.debug(this + " NOT started yet!");
+            }
+
             return null;
          }
-                        
+
+         if (trace) { log.trace(this + " has the main lock, preparing the message for delivery"); }
+
          JBossMessage message = (JBossMessage)ref.getMessage();
          
          boolean selectorRejected = !this.accept(message);
@@ -267,6 +275,7 @@
          {            
             try
             {
+               if (trace) { log.trace(this + " scheduling a new Deliverer"); }
                this.executor.execute(new Deliverer());
             }
             catch (InterruptedException e)
@@ -287,8 +296,8 @@
       boolean accept = true;
       if (this.destination.isQueue())
       {
-         //For subscriptions message selection is handled in the Subscription itself
-         //we do not want to do the check twice
+         // For subscriptions message selection is handled in the Subscription itself
+         // we do not want to do the check twice
          if (messageSelector != null)
          {
             accept = messageSelector.accept(r);
@@ -342,17 +351,19 @@
             // it. This is because it may still contain deliveries that may well be acknowledged
             // after the consumer has closed. This is perfectly valid.
 
-            //TODO - The deliveries should really be stored in the session endpoint, not here
-            //that is their natural place, that would mean we wouldn't have to mess around with keeping
-            //deliveries after this is closed
-                  
+            // FIXME - The deliveries should really be stored in the session endpoint, not here
+            // that is their natural place, that would mean we wouldn't have to mess around with
+            // keeping deliveries after this is closed.
+
+            if (trace) { log.trace(this + " grabbed the main lock in close()"); }
+
             disconnect(); 
             
             JMSDispatcher.instance.unregisterTarget(new Integer(id));
             
             //If this is a consumer of a non durable subscription
             //then we want to unbind the subscription and delete all it's data
-            
+
             if (destination.isTopic())
             {
                PostOffice topicPostOffice = 
@@ -379,6 +390,11 @@
          throw ExceptionUtil.handleJMSInvocation(t, this + " close");
       }
    }
+
+   public boolean isClosed()
+   {
+      return closed;
+   }
                
    // ConsumerEndpoint implementation -------------------------------
    
@@ -667,7 +683,6 @@
     */
    private void disconnect()
    {
-
       boolean removed = messageQueue.remove(this);
       
       if (removed)
@@ -711,68 +726,76 @@
       public void run()
       {
          // Is there anything to deliver?
-         // This is ok outside lock - is volatile
+         // This is ok outside lock - is volatile.
          if (clientConsumerFull)
          {
-            // Do nothing
+            if (trace) { log.trace(this + " client consumer full, do nothing"); }
             return;
          }
          
          List list = null;
              
          synchronized (lock)
-         {           
+         {
+            if (trace) { log.trace(this + " has the main lock, attempting delivery"); }
+
             if (!toDeliver.isEmpty())
             {
                list = new ArrayList(toDeliver);
-               
                toDeliver.clear();
-               
                bufferFull = false;
             }
          }
                                                            
-         if (list != null)
-         {         
-            ServerConnectionEndpoint connection =
-               ServerConsumerEndpoint.this.sessionEndpoint.getConnectionEndpoint();
+         if (list == null)
+         {
+            if (trace) { log.trace(this + " has a null list, returning"); }
+            return;
+         }
 
-            try
-            {
-               if (trace) { log.trace(ServerConsumerEndpoint.this + "handing " + list.size() + " message(s) over to the remoting layer"); }
-            
-               ClientDelivery del = new ClientDelivery(list, id);
-               
-               // TODO How can we ensure that messages for the same consumer aren't delivered
-               // concurrently to the same consumer on different threads?
-               MessagingMarshallable mm = new MessagingMarshallable(connection.getUsingVersion(), del);
-               
-               MessagingMarshallable resp = (MessagingMarshallable)connection.getCallbackClient().invoke(mm);
+         ServerConnectionEndpoint connection =
+            ServerConsumerEndpoint.this.sessionEndpoint.getConnectionEndpoint();
 
-               if (trace) { log.trace(ServerConsumerEndpoint.this + "handed messages over to the remoting layer"); }
-                
-               HandleMessageResponse result = (HandleMessageResponse)resp.getLoad();
+         try
+         {
+            if (trace) { log.trace(ServerConsumerEndpoint.this + " handing " + list.size() + " message(s) over to the remoting layer"); }
 
-               // For now we don't look at how many messages are accepted since they all will be.
-               // The field is a placeholder for the future.
-               if (result.clientIsFull())
-               {
-                  // Stop the server sending any more messages to the client.
-                  // This is ok outside lock.
-                  clientConsumerFull = true;       
-               }                               
-            }
-            catch(Throwable t)
+            ClientDelivery del = new ClientDelivery(list, id);
+
+            // TODO How can we ensure that messages for the same consumer aren't delivered
+            // concurrently to the same consumer on different threads?
+            MessagingMarshallable mm = new MessagingMarshallable(connection.getUsingVersion(), del);
+
+            MessagingMarshallable resp = (MessagingMarshallable)connection.getCallbackClient().invoke(mm);
+
+            if (trace) { log.trace(ServerConsumerEndpoint.this + " handed messages over to the remoting layer"); }
+
+            HandleMessageResponse result = (HandleMessageResponse)resp.getLoad();
+
+            // For now we don't look at how many messages are accepted since they all will be.
+            // The field is a placeholder for the future.
+            if (result.clientIsFull())
             {
-               log.warn("Failed to deliver the message to the client. See the server log for more details.");
-               log.debug(ServerConsumerEndpoint.this + " failed to deliver the message to the client.", t);
-               
-               ConnectionManager mgr = connection.getServerPeer().getConnectionManager();
-               
-               mgr.handleClientFailure(connection.getRemotingClientSessionId());
+               // Stop the server sending any more messages to the client.
+               // This is ok outside lock.
+               clientConsumerFull = true;
             }
-         }              
+         }
+         catch(Throwable t)
+         {
+            log.warn("Failed to deliver the message to the client. See the server log for more details.");
+            log.debug(ServerConsumerEndpoint.this + " failed to deliver the message to the client.", t);
+
+            ConnectionManager mgr = connection.getServerPeer().getConnectionManager();
+
+            mgr.handleClientFailure(connection.getRemotingClientSessionId());
+         }
       }
+
+      public String toString()
+      {
+         return "Deliverer[" + Integer.toHexString(hashCode()) + "]";
+      }
    }
    
    /*

Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -470,7 +470,7 @@
             throw new IllegalStateException("Session is already closed");
          }
          
-         if (trace) log.trace("close()");
+         if (trace) log.trace(this + " close()");
                
          // clone to avoid ConcurrentModificationException
          HashSet consumerSet = new HashSet(consumers.values());
@@ -495,8 +495,13 @@
    public void closing() throws JMSException
    {
       // currently does nothing
-      if (trace) log.trace("closing (noop)");
+      if (trace) log.trace(this + " closing (noop)");
    }
+
+   public boolean isClosed()
+   {
+      return closed;
+   }
    
    public void send(JBossMessage message) throws JMSException
    {

Modified: trunk/src/main/org/jboss/jms/server/endpoint/SessionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/SessionEndpoint.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/SessionEndpoint.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -111,7 +111,6 @@
     * This used at consumer close to cancel any undelivered messages left in the client buffer
     * or at session recovery to cancel any messages that couldn't be redelivered locally
     * @param ackInfos
-    * @throws Exception
     */
    void cancelDeliveries(List ackInfos) throws JMSException;
 }

Modified: trunk/src/main/org/jboss/jms/server/endpoint/advised/BrowserAdvised.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/advised/BrowserAdvised.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/advised/BrowserAdvised.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -65,6 +65,11 @@
       endpoint.closing();
    }
 
+   public boolean isClosed()
+   {
+      return endpoint.isClosed();
+   }
+
    public boolean hasNextMessage() throws JMSException
    {
       return endpoint.hasNextMessage();

Modified: trunk/src/main/org/jboss/jms/server/endpoint/advised/ConnectionAdvised.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/advised/ConnectionAdvised.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/advised/ConnectionAdvised.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -67,6 +67,11 @@
       endpoint.closing();
    }
 
+   public boolean isClosed()
+   {
+      return endpoint.isClosed();
+   }
+
    public SessionDelegate createSessionDelegate(boolean transacted,
                                                 int acknowledgmentMode,
                                                 boolean isXA) throws JMSException

Modified: trunk/src/main/org/jboss/jms/server/endpoint/advised/ConsumerAdvised.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/advised/ConsumerAdvised.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/advised/ConsumerAdvised.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -63,7 +63,12 @@
    {
       endpoint.closing();
    }
-   
+
+   public boolean isClosed()
+   {
+      return endpoint.isClosed();
+   }
+
    public void more() throws JMSException
    {
       endpoint.more();

Modified: trunk/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/server/endpoint/advised/SessionAdvised.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -72,7 +72,12 @@
    {
       endpoint.closing();
    }
-   
+
+   public boolean isClosed()
+   {
+      return endpoint.isClosed();
+   }
+
    public void send(JBossMessage msg) throws JMSException
    {
       endpoint.send(msg);

Modified: trunk/src/main/org/jboss/jms/tx/AckInfo.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/AckInfo.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/tx/AckInfo.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -32,6 +32,7 @@
  * for processing.
  * 
  * @author <a href="mailto:tim.fox at jboss.com>Tim Fox </a>
+ * @author <a href="mailto:ovidiu at jboss.com>Ovidiu Feodorov</a>
  *
  * $Id$
  */
@@ -42,8 +43,10 @@
    // Attributes ----------------------------------------------------
    
    protected long messageID;
-   
    protected int consumerID;
+
+   // One of Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE, etc.
+   private int ackMode;
    
    // The actual proxy must not get serialized
    protected transient MessageProxy msg;
@@ -55,18 +58,31 @@
    public AckInfo()
    {      
    }
-   
+
    public AckInfo(MessageProxy proxy, int consumerID)
    {
+      this(proxy, consumerID, -1);
+   }
+
+   /**
+    * @param ackMode - one of Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE, etc.
+    */
+   public AckInfo(MessageProxy proxy, int consumerID, int ackMode)
+   {
       this.msg = proxy;
       this.messageID = proxy.getMessage().getMessageID();
-      this.consumerID = consumerID;    
+      this.consumerID = consumerID;
+      this.ackMode = ackMode;
    }
    
-   public AckInfo(long messageID, int consumerID)
+   /**
+    * @param ackMode - one of Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE, etc.
+    */
+   public AckInfo(long messageID, int consumerID, int ackMode)
    {
       this.messageID = messageID;
       this.consumerID = consumerID;
+      this.ackMode = ackMode;
    }
 
    // Public --------------------------------------------------------
@@ -86,6 +102,16 @@
       return msg;
    }
 
+   /**
+    *
+    * @return one of Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE ..., or -1 if it has not
+    *         previously set
+    */
+   public int getAckMode()
+   {
+      return ackMode;
+   }
+
    public String toString()
    {
       return "AckInfo[" + messageID + ", " + consumerID + "]";

Modified: trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -111,6 +111,11 @@
       if (trace) { log.trace(this + " committing " + xid + (onePhase ? " (one phase)" : " (two phase)")); }
       
       rm.commit(xid, onePhase, connection);
+
+      // leave the session in a 'clean' state, the currentTxId will be set when the XAResource will
+      // be enrolled with a new transaction.
+
+      setCurrentTransactionId(null);
    }
 
    public void end(Xid xid, int flags) throws XAException
@@ -158,7 +163,10 @@
    public void rollback(Xid xid) throws XAException
    {
       if (trace) { log.trace(this + " rolling back " + xid); }
-  
+
+      // TODO on rollback should we also stop and start the consumers to remove any transient
+      // messages, like we do on local session rollback??
+
       rm.rollback(xid, connection);
    }
 
@@ -184,10 +192,11 @@
             case TMNOFLAGS :
                if (convertTx)
                {    
-                  //If I commit/rollback the tx, then there is a short period of time between the AS (or whoever)
-                  //calling commit on the tx and calling start to enrolling the session in a new tx.
-                  //If the session has any listeners then in that period, messages can be received asychronously
-                  //but we want them to be received in the context of a tx, so we convert.
+                  // If I commit/rollback the tx, then there is a short period of time between the
+                  // AS (or whoever) calling commit on the tx and calling start to enrolling the
+                  // session in a new tx. If the session has any listeners then in that period,
+                  // messages can be received asychronously but we want them to be received in the
+                  // context of a tx, so we convert.
                   setCurrentTransactionId(rm.convertTx((LocalTx)sessionState.getCurrentTxId(), xid));
                }
                else
@@ -231,11 +240,6 @@
    
    private void setCurrentTransactionId(final Xid xid)
    {
-      if (xid == null)
-      {
-         throw new NullPointerException("null xid");
-      }
-
       if (trace) { log.trace(this + " setting current xid to " + xid + ",  previous " + sessionState.getCurrentTxId()); }
 
       sessionState.setCurrentTxId(xid);
@@ -245,7 +249,7 @@
    {
       if (xid == null)
       {
-         throw new org.jboss.util.NullArgumentException("xid");
+         throw new IllegalArgumentException("xid must be not null");
       }
 
       if (trace) { log.trace(this + " unsetting current xid " + xid + ",  previous " + sessionState.getCurrentTxId()); }

Modified: trunk/src/main/org/jboss/jms/tx/ResourceManagerFactory.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/ResourceManagerFactory.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/jms/tx/ResourceManagerFactory.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -58,7 +58,7 @@
    /**
     * @param serverID - server peer ID.
     */
-   public synchronized ResourceManager getResourceManager(String serverID)
+   public synchronized ResourceManager checkOutResourceManager(String serverID)
    {
       Holder h = (Holder)holders.get(serverID);
       
@@ -76,7 +76,7 @@
       return h.rm;
    }
    
-   public synchronized void returnResourceManager(String serverID)
+   public synchronized void checkInResourceManager(String serverID)
    {
       Holder h = (Holder)holders.get(serverID);
       

Modified: trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/ChannelSupport.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/messaging/core/ChannelSupport.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -440,12 +440,16 @@
       return undelivered;
    }
 
+   /**
+    * Returns the count of messages stored AND being delivered.
+    */
    public int messageCount()
    {   
       synchronized (refLock)
       {
          synchronized (deliveryLock)
          {
+            //return messageRefs.size() + refsInStorage + deliveries.size();
             return messageRefs.size() + deliveries.size();
          }
       }
@@ -576,36 +580,41 @@
                {
                   // Reference is not expired
 
-                  // Attempt to push the ref to a receiver
+                  // Attempt to push the ref to a receiver, so increment the delivery count
+                  ref.incrementDeliveryCount();
+
                   Delivery del = router.handle(this, ref, null);
 
                   if (del == null)
                   {
-                     // no receiver, broken receiver
-                     // or full receiver    
-                     // so we stop delivering
-                     if (trace) { log.trace(this + ": no delivery returned for message" 
-                                  + ref + " so no receiver got the message");
-                                  log.trace("Delivery is now complete"); }
+                     // No receiver, broken receiver or full receiver so we stop delivering; also
+                     // we need to decrement the delivery count, as no real delivery has been
+                     // actually performed
 
+                     if (trace) { log.trace(this + ": no delivery returned for message" + ref + " so no receiver got the message. Delivery is now complete"); }
+
+                     ref.decrementDeliveryCount();
                      receiversReady = false;
-
                      return;
                   }
                   else if (!del.isSelectorAccepted())
                   {
-                     // No receiver accepted the message because no selectors matched
-                     // So we create an iterator (if we haven't already created it) to
-                     // iterate through the refs in the channel
-                     // TODO Note that this is only a partial solution since if there are messages paged to storage
-                     // it won't try those - i.e. it will only iterate through those refs in memory.
-                     // Dealing with refs in storage is somewhat tricky since we can't just load them and iterate
-                     // through them since we might run out of memory
-                     // So we will need to load individual refs from storage given the selector expressions
-                     // Secondly we should also introduce some in memory indexes here to prevent having to
-                     // iterate through all the refs every time
-                     // Having said all that, having consumers on a queue that don't match many messages
-                     // is an antipattern and should be avoided by the user
+                     // No receiver accepted the message because no selectors matched, so we create
+                     // an iterator (if we haven't already created it) to iterate through the refs
+                     // in the channel. No delivery was really performed, so we decrement the
+                     // delivery count
+
+                     ref.decrementDeliveryCount();
+
+                     // TODO Note that this is only a partial solution since if there are messages
+                     // paged to storage it won't try those - i.e. it will only iterate through
+                     // those refs in memory. Dealing with refs in storage is somewhat tricky since
+                     // we can't just load them and iterate through them since we might run out of
+                     // memory, so we will need to load individual refs from storage given the
+                     // selector expressions. Secondly we should also introduce some in memory
+                     // indexes here to prevent having to iterate through all the refs every time.
+                     // Having said all that, having consumers on a queue that don't match many
+                     // messages is an antipattern and should be avoided by the user.
                      if (iter == null)
                      {
                         iter = messageRefs.iterator();
@@ -615,15 +624,12 @@
                   {
                      if (trace) { log.trace(this + ": " + del + " returned for message:" + ref); }
                      
-                     //Receiver accepted the reference
+                     // Receiver accepted the reference
 
-                     // We must synchronize here to cope with another race
-                     // condition where message is
-                     // cancelled/acked in flight while the following few
-                     // actions are being performed.
-                     // e.g. delivery could be cancelled acked after being
-                     // removed from state but before
-                     // delivery being added (observed).
+                     // We must synchronize here to cope with another race condition where message
+                     // is cancelled/acked in flight while the following few actions are being
+                     // performed. e.g. delivery could be cancelled acked after being removed from
+                     // state but before delivery being added (observed).
                      synchronized (del)
                      {
                         if (trace) { log.trace(this + " incrementing delivery count for " + del); }
@@ -1101,7 +1107,7 @@
    {
       // by default a noop
    }
-   
+
    protected void checkClosed()
    {
       if (router == null)

Modified: trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/messaging/core/local/FirstReceiverPointToPointRouter.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -71,45 +71,56 @@
 
    public Delivery handle(DeliveryObserver observer, MessageReference ref, Transaction tx)
    {
+      ArrayList receiversCopy;
+
+      synchronized(receivers)
+      {
+         if (receivers.isEmpty())
+         {
+            return null;
+         }
+
+         // try to release the lock as quickly as possible and make a copy of the receivers array
+         // to avoid deadlock
+
+         receiversCopy = new ArrayList(receivers.size());
+         receiversCopy.addAll(receivers);
+      }
+
       Delivery del = null;
-      
       boolean selectorRejected = false;
-      
-      synchronized(receivers)
+
+      for(Iterator i = receiversCopy.iterator(); i.hasNext(); )
       {
-         for(Iterator i = receivers.iterator(); i.hasNext(); )
+         Receiver receiver = (Receiver)i.next();
+
+         try
          {
-            Receiver receiver = (Receiver)i.next();
-            
-            try
+            Delivery d = receiver.handle(observer, ref, tx);
+
+            if (trace) { log.trace("receiver " + receiver + " handled " + ref + " and returned " + d); }
+
+            if (d != null && !d.isCancelled())
             {
-               Delivery d = receiver.handle(observer, ref, tx);
-
-               if (trace) { log.trace("receiver " + receiver + " handled " + ref + " and returned " + d); }
-     
-               if (d != null && !d.isCancelled())
+               if (d.isSelectorAccepted())
                {
-                  if (d.isSelectorAccepted())
-                  {
-                     // deliver to the first receiver that accepts
-                     del = d;
-                     
-                     break;
-                  }
-                  else
-                  {
-                     selectorRejected = true;
-                  }
+                  // deliver to the first receiver that accepts
+                  del = d;
+                  break;
                }
+               else
+               {
+                  selectorRejected = true;
+               }
             }
-            catch(Throwable t)
-            {
-               // broken receiver - log the exception and ignore it
-               log.error("The receiver " + receiver + " is broken", t);
-            }
          }
+         catch(Throwable t)
+         {
+            // broken receiver - log the exception and ignore it
+            log.error("The receiver " + receiver + " is broken", t);
+         }
       }
-      
+
       if (del == null && selectorRejected)
       {
          del = new SimpleDelivery(null, null, true, false);
@@ -118,6 +129,7 @@
       return del;
    }
 
+
    public boolean add(Receiver r)
    {
       synchronized(receivers)

Modified: trunk/src/main/org/jboss/messaging/core/message/RoutableSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/message/RoutableSupport.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/messaging/core/message/RoutableSupport.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -111,7 +111,7 @@
       this.timestamp = timestamp;
       this.priority = priority;
       this.deliveryCount = deliveryCount;
-      this.redelivered = deliveryCount >= 1;      
+      this.redelivered = deliveryCount >= 2;
       if (headers == null)
       {
          this.headers = new HashMap();

Modified: trunk/src/main/org/jboss/messaging/core/tx/Transaction.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/Transaction.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/messaging/core/tx/Transaction.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -32,13 +32,15 @@
 import org.jboss.logging.Logger;
 
 /**
- * 
+ *
  * A JMS Server local transaction
- * 
+ *
  * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
  * @author <a href="mailto:ovidiu at jboss.com">Ovidiu Feodorov</a>
- * 
+ *
  * @version $Revision 1.1$
+ *
+ * $Id$
  */
 public class Transaction
 {
@@ -47,37 +49,40 @@
    private static final Logger log = Logger.getLogger(Transaction.class);
 
    // Attributes ----------------------------------------------------
-   
+
    private boolean trace = log.isTraceEnabled();
-     
+
    protected long id;
-   
+
    protected int state;
-   
+
    protected Xid xid;
-   
+
+   /**
+    * If this is a XA transaction, when a commit is executed the transaction has to be removed from the transaction repository.
+    * This reference will guarantee the reference back to the repository where the transaction was created
+    * */
+   protected TransactionRepository transactionRepository;
+
    protected List callbacks;
-   
-   protected Map callbackMap;
-   
-   protected TransactionRepository repository;
-   
-   //A special first callback that is ensured to be executed first
-   protected TxCallback firstCallback;
-   
+
+   protected List keyedCallbacks;
+
+   protected Map keyedCallbackMap;
+
    // Static --------------------------------------------------------
-   
+
    public static final int STATE_ACTIVE = 0;
-   
+
    public static final int STATE_PREPARED = 1;
-   
+
    public static final int STATE_COMMITTED = 2;
-   
+
    public static final int STATE_ROLLEDBACK = 3;
 
    public static final int STATE_ROLLBACK_ONLY = 4;
 
-   public String stateToString(int state)
+   public static String stateToString(int state)
    {
       if (state == STATE_ACTIVE)
       {
@@ -106,58 +111,52 @@
    }
 
    // Constructors --------------------------------------------------
-   
+
    Transaction(long id)
    {
       this.id = id;
       state = STATE_ACTIVE;
       callbacks = new ArrayList();
-      callbackMap = new HashMap();
+      keyedCallbacks = new ArrayList();
+      keyedCallbackMap = new HashMap();
    }
-   
-   Transaction(long id, Xid xid, TransactionRepository tr)
+
+   Transaction(long id, Xid xid, TransactionRepository repository)
    {
       this(id);
       this.xid = xid;
-      this.repository = tr;
+      this.transactionRepository=repository;
    }
-   
+
    // Public --------------------------------------------------------
-   
+
    public int getState()
    {
       return state;
-   }      
-   
+   }
+
    public Xid getXid()
    {
       return xid;
    }
 
-   public void addCallback(TxCallback callback, Object key)
-   {            
+   public void addCallback(TxCallback callback)
+   {
       callbacks.add(callback);
-      
-      callbackMap.put(key, callback);
-   } 
-   
-   public void addFirstCallback(TxCallback callback, Object key)
-   {            
-      if (firstCallback != null)
-      {
-         throw new IllegalStateException("There is already a first callback");
-      }
-      
-      this.firstCallback = callback;
-      
-      callbackMap.put(key, callback);
    }
-   
-   public TxCallback getCallback(Object key)
+
+   public void addKeyedCallback(TxCallback callback, Object key)
    {
-      return (TxCallback)callbackMap.get(key);
+      keyedCallbacks.add(callback);
+
+      keyedCallbackMap.put(key, callback);
    }
-      
+
+   public TxCallback getKeyedCallback(Object key)
+   {
+      return (TxCallback)keyedCallbackMap.get(key);
+   }
+
    public synchronized void commit() throws Exception
    {
       if (state == STATE_ROLLBACK_ONLY)
@@ -174,98 +173,89 @@
       }
 
       if (trace) { log.trace("executing before commit hooks " + this); }
-       
+
       boolean onePhase = state != STATE_PREPARED;
-      
-      if (firstCallback != null)
-      {
-         firstCallback.beforeCommit(onePhase);
-      }
-      
-      Iterator iter = callbacks.iterator();
-      
+
+      List cb = new ArrayList(callbacks);
+      cb.addAll(keyedCallbacks);
+
+      Iterator iter = cb.iterator();
+
       while (iter.hasNext())
       {
          TxCallback callback = (TxCallback)iter.next();
-         
+
          callback.beforeCommit(onePhase);
       }
-      
+
       state = STATE_COMMITTED;
-      
+
       if (trace) { log.trace("committed " + this); }
-      
-      iter = callbacks.iterator();
-      
+
+      iter = cb.iterator();
+
       if (trace) { log.trace("executing after commit hooks " + this); }
-      
-      if (firstCallback != null)
-      {
-         firstCallback.afterCommit(onePhase);
-      }
-      
+
       while (iter.hasNext())
       {
          TxCallback callback = (TxCallback)iter.next();
-         
+
          callback.afterCommit(onePhase);
       }
-          
+
       callbacks = null;
-      
-      callbackMap = null;      
-      
-      firstCallback = null;
-      
-      if (trace) { log.trace("commit process complete " + this); }            
+
+      keyedCallbacks = null;
+
+      keyedCallbackMap = null;
+
+      if (transactionRepository!=null)
+      {
+    	  transactionRepository.deleteTransaction(this);
+      }
+
+      if (trace) { log.trace("commit process complete " + this); }
    }
-   
+
    public synchronized void prepare() throws Exception
    {
       if (state != STATE_ACTIVE)
       {
          throw new TransactionException("Transaction not active, cannot prepare");
       }
-      
+
       if (trace) { log.trace("executing before prepare hooks " + this); }
-      
-      if (firstCallback != null)
-      {
-         firstCallback.beforePrepare();
-      }
-      
-      Iterator iter = callbacks.iterator();
-      
+
+      List cb = new ArrayList(callbacks);
+      cb.addAll(keyedCallbacks);
+
+      Iterator iter = cb.iterator();
+
       while (iter.hasNext())
       {
          TxCallback callback = (TxCallback)iter.next();
-         
+
          callback.beforePrepare();
       }
-      
+
       state = STATE_PREPARED;
-      
+
       if (trace) { log.trace("prepared " + this); }
-      
-      if (firstCallback != null)
-      {
-         firstCallback.afterPrepare();
-      }
-      
-      iter = callbacks.iterator();
-      
+
+      iter = cb.iterator();
+
       if (trace) { log.trace("executing after prepare hooks " + this); }
-      
+
       while (iter.hasNext())
       {
          TxCallback callback = (TxCallback)iter.next();
-         
+
          callback.afterPrepare();
-      }            
-      
+      }
+
       if (trace) { log.trace("prepare process complete " + this); }
    }
-   
+
    public synchronized void rollback() throws Exception
    {
       if (state == STATE_COMMITTED)
@@ -276,42 +266,41 @@
       {
          throw new TransactionException("Transaction already rolled back, cannot rollback");
       }
-      
+
       if (trace) { log.trace("executing before rollback hooks " + this); }
-      
+
       boolean onePhase = state != STATE_PREPARED;
-      
-      if (firstCallback != null)
-      {
-         firstCallback.beforeRollback(onePhase);
-      }
 
-      for(Iterator i = callbacks.iterator(); i.hasNext(); )
+      List cb = new ArrayList(callbacks);
+      cb.addAll(keyedCallbacks);
+
+      for(Iterator i = cb.iterator(); i.hasNext(); )
       {
          TxCallback callback = (TxCallback)i.next();
          callback.beforeRollback(onePhase);
       }
-      
+
       state = STATE_ROLLEDBACK;
-      
+
       if (trace) { log.trace("rolled back " + this); }
 
       if (trace) { log.trace("executing after prepare hooks " + this); }
 
-      if (firstCallback != null)
+      for(Iterator i = cb.iterator(); i.hasNext();)
       {
-         firstCallback.afterRollback(onePhase);
-      }
-      
-      for(Iterator i = callbacks.iterator(); i.hasNext();)
-      {
          TxCallback callback = (TxCallback)i.next();
          callback.afterRollback(onePhase);
-      }            
-      
+      }
+
       callbacks = null;
-      callbackMap = null;
-      
+      keyedCallbacks = null;
+      keyedCallbackMap = null;
+
+      if (transactionRepository!=null)
+      {
+    	  transactionRepository.deleteTransaction(this);
+      }
+
       if (trace) { log.trace("rollback process complete " + this); }
    }
 
@@ -321,12 +310,12 @@
 
       state = STATE_ROLLBACK_ONLY;
    }
-   
+
    public long getId()
    {
       return id;
    }
-      
+
    public String toString()
    {
       StringBuffer sb = new StringBuffer("TX(");
@@ -337,13 +326,13 @@
    }
 
    // Package protected ---------------------------------------------
-   
+
    // Protected -----------------------------------------------------
-   
+
    // Private -------------------------------------------------------
-   
+
    // Inner classes -------------------------------------------------
-   
+
 }
 
 

Modified: trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -140,6 +140,29 @@
       return tx;
    }
    
+   public void deleteTransaction(Transaction transaction) throws Exception
+   {
+	   final Xid id = transaction.getXid();
+	   final int state = transaction.getState();
+	   
+	   if (id==null)
+	   {
+		   Exception ex = new Exception();
+		   log.warn("DeleteTransaction was called for non XA transaction",ex);
+		   return;
+	   }
+
+	   if (state!=Transaction.STATE_COMMITTED && state!=Transaction.STATE_ROLLEDBACK)
+	   {
+		   throw new TransactionException("Transaction with xid " + id + " can't be removed as it's not yet commited or rolledback: (Current state is " + Transaction.stateToString(state));
+	   }
+	   
+	   globalToLocalMap.remove(id);
+	   
+	   
+	   
+   }
+   
    public Transaction createTransaction(Xid xid) throws Exception
    {
       if (globalToLocalMap.containsKey(xid))
@@ -169,6 +192,12 @@
       return globalToLocalMap.remove(xid) != null;
    }
    
+   /** To be used only by testcases */
+   public int getNumberOfRegisteredTransactions()
+   {
+	  return this.globalToLocalMap.size();   
+   }
+   
    // Package protected ---------------------------------------------
    
    // Protected -----------------------------------------------------         

Modified: trunk/tests/bin/loop
===================================================================
--- trunk/tests/bin/loop	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/bin/loop	2006-09-27 07:55:32 UTC (rev 1368)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 
-count=500
+count=5000
 i=0
 
 while [ $i -lt $count ]; do
@@ -20,7 +20,6 @@
 done
 
 
-
 echo "#############################################"
 echo "#                                           #"
 echo "#      $count loops ran successfully" 

Modified: trunk/tests/build.xml
===================================================================
--- trunk/tests/build.xml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/build.xml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -529,7 +529,7 @@
                <exclude name="org/jboss/test/messaging/jms/ManualCrashTest.class"/>
                <exclude name="org/jboss/test/messaging/jms/MemLeakTest.class"/>
                <exclude name="org/jboss/test/messaging/jms/ManifestTest.class"/>
-               <exclude name="org/jboss/test/messaging/jms/XATransactionTest.class"/>
+               <exclude name="org/jboss/test/messaging/jms/JCAWrapperTest.class"/>
             </fileset>
          </batchtest>
       </junit>
@@ -607,6 +607,12 @@
       <antcall target="start-rmi-server"/>
 
       <antcall target="crash-test">
+         <param name="crash.test.name" value="org.jboss.test.messaging.jms.crash.ClientCrashTwoConnectionsTest"/>
+      </antcall>
+   	
+      <antcall target="start-rmi-server"/>
+
+      <antcall target="crash-test">
           <param name="crash.test.name" value="org.jboss.test.messaging.jms.crash.ClientCrashNegativeLeaseTest"/>
       </antcall>
 

Modified: trunk/tests/etc/log4j.trace.xml
===================================================================
--- trunk/tests/etc/log4j.trace.xml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/etc/log4j.trace.xml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -66,6 +66,10 @@
       <priority value="DEBUG"/>
    </category>
 
+   <category name="org.jboss.jms.server.remoting.JMSWireFormat">
+      <priority value="DEBUG"/>
+   </category>
+
    <root>
       <appender-ref ref="CONSOLE"/>
       <appender-ref ref="FILE"/>

Modified: trunk/tests/etc/log4j.xml
===================================================================
--- trunk/tests/etc/log4j.xml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/etc/log4j.xml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -66,6 +66,10 @@
       <priority value="DEBUG"/>
    </category>
 
+   <category name="org.jboss.jms.server.remoting.JMSWireFormat">
+      <priority value="DEBUG"/>
+   </category>
+
    <root>
       <appender-ref ref="CONSOLE"/>
       <appender-ref ref="FILE"/>

Copied: trunk/tests/lib/README (from rev 1367, branches/Branch_1_0/tests/lib/README)

Modified: trunk/tests/lib/jms-ra.jar
===================================================================
(Binary files differ)

Modified: trunk/tests/smoke/build.xml
===================================================================
--- trunk/tests/smoke/build.xml	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/smoke/build.xml	2006-09-27 07:55:32 UTC (rev 1368)
@@ -125,6 +125,18 @@
          <param name="run.secure-socket.example" value="false"/>
       </antcall>
 
+      <antcall target="installation-test">
+         <param name="jboss.home" value="${jboss405CR1.home}"/>
+      </antcall>
+
+      <antcall target="installation-test">
+         <param name="jboss.home" value="${jboss405CR1.home}"/>
+         <param name="release.admin.target" value="standalone"/>
+         <param name="run.mdb.example" value="false"/>
+         <param name="run.stateless.example" value="false"/>
+         <param name="run.secure-socket.example" value="false"/>
+      </antcall>
+
       <!--
          Stateless Session Bean installation test will fail on this because the client talks to
          Messaging's remoting and to Unified Invoker's remoting and runs into compatibility

Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -1184,6 +1184,15 @@
          tx = txRep.createTransaction();
       }
       
+      if (xa)
+      {
+    	  assertEquals(1,txRep.getNumberOfRegisteredTransactions());
+      }
+      else
+      {
+    	  assertEquals(0,txRep.getNumberOfRegisteredTransactions());
+      }
+      
       MessageReference ref1 = ms.reference(m1);
       MessageReference ref2 = ms.reference(m2);  
       MessageReference ref3 = ms.reference(m3);       
@@ -1235,6 +1244,8 @@
       
       //commit transaction
       tx.commit();
+
+      assertEquals("numberOfRegisteredTransactions",0,txRep.getNumberOfRegisteredTransactions());
       
       //check we can see only the last 3 refs
       refs = getReferenceIds(channel.getChannelID());

Modified: trunk/tests/src/org/jboss/test/messaging/jms/CreateTwoClientOnServerCommand.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/CreateTwoClientOnServerCommand.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/CreateTwoClientOnServerCommand.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -1,3 +1,4 @@
+<<<<<<< .working
 /*
   * JBoss, Home of Professional Open Source
   * Copyright 2005, JBoss Inc., and individual contributors as indicated
@@ -96,3 +97,99 @@
 	   }
 
 	}
+=======
+/*
+  * 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.
+  */
+package org.jboss.test.messaging.jms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Topic;
+
+import org.jboss.jms.client.JBossConnection;
+import org.jboss.test.messaging.tools.jmx.rmi.Command;
+
+/**
+ * 
+ * A CreateClientOnServerCommand.
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="clebert.suconic at jboss.com">Clebert Suconic</a>
+ * @version 1.1
+ *
+ * $Id$
+ */
+public class CreateTwoClientOnServerCommand implements Command
+{
+	   private static final long serialVersionUID = -997724797145152821L;
+	   
+	   private ConnectionFactory cf;
+	   
+	   private boolean retainReference;
+	   
+	   private static List commands = new ArrayList();
+	   
+	   Topic topic;
+	   Connection conn1;
+	   Connection conn2;
+	   
+	   public CreateTwoClientOnServerCommand(ConnectionFactory cf,  Topic topic, boolean retainReference)
+	   {
+	      this.cf = cf;
+	      this.topic = topic;
+	      
+	      this.retainReference = retainReference;
+	   }
+	   
+	   /*
+	    * Just create a connection, send and receive a message and leave the connection open.
+	    */
+	   public Object execute() throws Exception
+	   {
+	      if (retainReference)
+	      {
+	         commands.add(this);
+	      }
+	      
+	      conn1 = cf.createConnection();
+	      conn1.setClientID("test1");
+	      conn1.start();
+
+	      conn2 = cf.createConnection();
+	      conn2.setClientID("test2");
+	      conn2.start();
+
+	      conn1.close();
+	      
+	      String arrays[] = new String[2];
+	      arrays[0] = ((JBossConnection)conn1).getRemotingClientSessionId();
+	      arrays[1] = ((JBossConnection)conn2).getRemotingClientSessionId();
+
+	      // Return the remoting client session id for the connection
+	      return arrays;      
+	   }
+
+	}
+>>>>>>> .merge-right.r1367

Added: trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriberTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriberTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriberTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -0,0 +1,470 @@
+/*
+  * 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.
+  */
+package org.jboss.test.messaging.jms;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.DeliveryMode;
+import javax.jms.InvalidDestinationException;
+import javax.jms.InvalidSelectorException;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.management.ObjectName;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.tools.ServerManagement;
+
+
+/**
+ * Tests focused on durable subscription behavior. More durable subscription tests can be found in
+ * MessageConsumerTest.
+ *
+ * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ * $Id: DurableSubscriberTest.java 1319 2006-09-19 17:17:53Z ovidiu.feodorov at jboss.com $
+ */
+public class DurableSubscriberTest extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   // Attributes ----------------------------------------------------
+
+   protected InitialContext ic;
+
+   // Constructors --------------------------------------------------
+
+   public DurableSubscriberTest(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+
+      ServerManagement.start("all");
+            
+      ServerManagement.undeployTopic("Topic");
+      ServerManagement.deployTopic("Topic");
+
+      ic = new InitialContext(ServerManagement.getJNDIEnvironment());
+
+      log.debug("setup done");
+   }
+
+   public void tearDown() throws Exception
+   {
+      log.debug("starting tear down");
+
+      ic.close();
+
+      ServerManagement.undeployTopic("Topic");
+        
+      super.tearDown();
+   }
+
+   public void testSimplestDurableSubscription() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
+      Topic topic = (Topic)ic.lookup("/topic/Topic");
+      Connection conn = cf.createConnection();
+
+      conn.setClientID("brookeburke");
+
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = s.createProducer(topic);
+      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+
+      s.createDurableSubscriber(topic, "monicabelucci");
+
+      ObjectName destObjectName =
+         new ObjectName("jboss.messaging.destination:service=Topic,name=Topic");
+      String text = (String)ServerManagement.invoke(destObjectName, "listSubscriptionsAsText", null, null);
+
+      assertTrue(text.indexOf("monicabelucci") != -1);
+
+      prod.send(s.createTextMessage("k"));
+
+      conn.close();
+
+      text = (String)ServerManagement.invoke(destObjectName, "listSubscriptionsAsText", null, null);
+
+      assertTrue(text.indexOf("monicabelucci") != -1);
+
+      conn = cf.createConnection();
+      conn.setClientID("brookeburke");
+
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+      MessageConsumer durable = s.createDurableSubscriber(topic, "monicabelucci");
+
+      conn.start();
+
+      TextMessage tm = (TextMessage)durable.receive();
+      assertEquals("k", tm.getText());
+
+      Message m = durable.receive(1000);
+      assertNull(m);
+   }
+
+   /**
+    * JMS 1.1 6.11.1: A client can change an existing durable subscription by creating a durable
+    * TopicSubscriber with the same name and a new topic and/or message selector, or NoLocal
+    * attribute. Changing a durable subscription is equivalent to deleting and recreating it.
+    *
+    * Test with a different topic (a redeployed topic is a different topic).
+    */
+   public void testDurableSubscriptionOnNewTopic() throws Exception
+   {
+      ServerManagement.deployTopic("CompletelyNewTopic");
+
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
+      Topic topic = (Topic)ic.lookup("/topic/CompletelyNewTopic");
+      Connection conn = cf.createConnection();
+
+      conn.setClientID("brookeburke");
+
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = s.createProducer(topic);
+      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+
+      s.createDurableSubscriber(topic, "monicabelucci");
+
+      prod.send(s.createTextMessage("one"));
+
+      conn.close();
+
+      ServerManagement.deployTopic("CompletelyNewTopic2");
+
+      Topic topic2 = (Topic)ic.lookup("/topic/CompletelyNewTopic2");
+      conn = cf.createConnection();
+
+      conn.setClientID("brookeburke");
+
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageConsumer durable = s.createDurableSubscriber(topic2, "monicabelucci");
+
+      conn.start();
+
+      Message m = durable.receive(1000);
+      assertNull(m);
+
+      ServerManagement.undeployTopic("CompletelyNewTopic");
+      ServerManagement.undeployTopic("CompletelyNewTopic2");
+   }
+
+   /**
+    * JMS 1.1 6.11.1: A client can change an existing durable subscription by creating a durable
+    * TopicSubscriber with the same name and a new topic and/or message selector, or NoLocal
+    * attribute. Changing a durable subscription is equivalent to deleting and recreating it.
+    *
+    * Test with a different selector.
+    */
+   public void testDurableSubscriptionDifferentSelector() throws Exception
+   {
+      ServerManagement.deployTopic("CompletelyNewTopic2");
+      
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
+      Topic topic = (Topic)ic.lookup("/topic/Topic");
+      Connection conn = cf.createConnection();
+
+      conn.setClientID("brookeburke");
+
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = s.createProducer(topic);
+      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+
+      
+      //fails here
+      MessageConsumer durable =
+         s.createDurableSubscriber(topic,
+                                   "monicabelucci",
+                                   "color = 'red' AND shape = 'square'",
+                                   false);
+
+      TextMessage tm = s.createTextMessage("A red square message");
+      tm.setStringProperty("color", "red");
+      tm.setStringProperty("shape", "square");
+      prod.send(tm);
+
+      conn.start();
+
+      TextMessage rm = (TextMessage)durable.receive(5000);
+      assertEquals("A red square message", rm.getText());
+
+      tm = s.createTextMessage("Another red square message");
+      tm.setStringProperty("color", "red");
+      tm.setStringProperty("shape", "square");
+      prod.send(tm);
+
+      // TODO: when subscriptions/durable subscription will be registered as MBean, use the JMX
+      //       interface to make sure the 'another red square message' is maintained by the
+      //       durable subascription
+      //       http://jira.jboss.org/jira/browse/JBMESSAGING-217
+
+      conn.close();
+
+      conn = cf.createConnection();
+
+      conn.setClientID("brookeburke");
+
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+      // modify the selector
+      durable = s.createDurableSubscriber(topic,
+                                          "monicabelucci",
+                                          "color = 'red'",
+                                          false);
+
+      conn.start();
+
+      Message m = durable.receive(1000);
+
+      // the durable subscription is destroyed and re-created. The red square message stored by
+      // the previous durable subscription is lost and (hopefully) garbage collected.
+      assertNull(m);
+      
+      ServerManagement.undeployTopic("CompletelyNewTopic2");
+   }
+
+   /**
+    * JMS 1.1 6.11.1: A client can change an existing durable subscription by creating a durable
+    * TopicSubscriber with the same name and a new topic and/or message selector, or NoLocal
+    * attribute. Changing a durable subscription is equivalent to deleting and recreating it.
+    *
+    * Test with a different noLocal flag.
+    */
+   public void testDurableSubscriptionDifferentNoLocal() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
+      Topic topic = (Topic)ic.lookup("/topic/Topic");
+
+      Connection conn = cf.createConnection();
+      conn.setClientID("ID0");
+
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = s.createProducer(topic);
+      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+
+      MessageConsumer durable = s.createDurableSubscriber(topic, "mySubscription", null, false);
+
+      TextMessage tm = null;
+      tm = s.createTextMessage("Message One");
+      prod.send(tm);
+      tm = s.createTextMessage("Message Two");
+      prod.send(tm);
+
+
+      conn.start();
+
+      TextMessage rm = (TextMessage)durable.receive(5000);
+      assertEquals("Message One", rm.getText());
+
+      conn.close();
+
+      conn = cf.createConnection();
+      conn.setClientID("ID0");
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+      // modify the nolocal flag
+      durable = s.createDurableSubscriber(topic, "mySubscription", null, true);
+
+      conn.start();
+
+      Message m = durable.receive(1000);
+
+      // the durable subscription is destroyed and re-created. "Message Two" stored by the previous
+      // durable subscription is lost and (hopefully) garbage collected.
+      assertNull(m);
+   }
+
+   public void testDurableSubscriptionOnTemporaryTopic() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
+      Connection conn = cf.createConnection();
+      conn.setClientID("doesn't actually matter");
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      Topic temporaryTopic = s.createTemporaryTopic();
+
+      try
+      {
+         s.createDurableSubscriber(temporaryTopic, "mySubscription");
+         fail("this should throw exception");
+      }
+      catch(InvalidDestinationException e)
+      {
+         // OK
+      }
+   }
+
+   /**
+    * Topic undeployment/redeployment has an activation/deactivation semantic, so undeploying a
+    * topic for which there are durable subscriptions preserves the content of those durable
+    * subscriptions, which can be then access upon topic redeployment.
+    * @throws Exception
+    */
+   public void testDurableSubscriptionOnTopicRedeployment() throws Exception
+   {
+      try
+      {
+         ic.lookup("/topic/TopicToBeRedeployed");
+         fail("should throw exception, topic shouldn't be deployed on the server");
+      }
+      catch(NamingException e)
+      {
+         // OK
+      }
+
+      ServerManagement.deployTopic("TopicToBeRedeployed");
+
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
+      Topic topic = (Topic)ic.lookup("/topic/TopicToBeRedeployed");
+
+      Connection conn = cf.createConnection();
+      conn.setClientID("brookeburke");
+
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = s.createProducer(topic);
+      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+      MessageConsumer ds = s.createDurableSubscriber(topic, "monicabelucci");
+      conn.start();
+
+      prod.send(s.createTextMessage("one"));
+      prod.send(s.createTextMessage("two"));
+
+      ServerManagement.undeployTopic("TopicToBeRedeployed");
+      log.debug("topic undeployed");
+
+      try
+      {
+         topic = (Topic)ic.lookup("/topic/TopicToBeRedeployed");
+         fail("should throw exception");
+      }
+      catch(NamingException e)
+      {
+         // OK
+      }
+
+      TextMessage tm = (TextMessage)ds.receive();
+      assertEquals("one", tm.getText());
+      conn.close();
+
+      conn = cf.createConnection();
+      conn.setClientID("brookeburke");
+
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+      try
+      {
+         s.createDurableSubscriber(topic, "monicabelucci");
+         fail("should throw exception");
+      }
+      catch(JMSException e)
+      {
+         // OK
+      }
+
+      ServerManagement.deployTopic("TopicToBeRedeployed");
+      log.debug("topic redeployed");
+
+      // since redeployment has an activation semantic, I expect to find the messages there
+
+      topic = (Topic)ic.lookup("/topic/TopicToBeRedeployed");
+      ds =  s.createDurableSubscriber(topic, "monicabelucci");
+      conn.start();
+
+      tm = (TextMessage)ds.receive(1000);
+      assertEquals("two", tm.getText());
+
+      conn.close();
+      ServerManagement.undeployTopic("TopicToBeRedeployed");
+   }
+
+   public void testUnsubscribeDurableSubscription() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
+      Topic topic = (Topic)ic.lookup("/topic/Topic");
+
+      Connection conn = cf.createConnection();
+      conn.setClientID("ak47");
+
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      s.createDurableSubscriber(topic, "uzzi");
+      MessageProducer prod = s.createProducer(topic);
+      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+
+      prod.send(s.createTextMessage("one"));
+
+      log.debug("unsubscribing ...");
+
+      s.unsubscribe("uzzi");
+
+      log.debug("resubscribing ...");
+
+      MessageConsumer ds = s.createDurableSubscriber(topic, "uzzi");
+      conn.start();
+
+      assertNull(ds.receive(1000));
+
+      conn.close();
+   }
+
+   public void testInvalidSelectorException() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
+      Topic topic = (Topic)ic.lookup("/topic/Topic");
+      Connection c = cf.createConnection();
+      c.setClientID("sofiavergara");
+      Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+      try
+      {
+         s.createDurableSubscriber(topic, "mysubscribption", "=TEST 'test'", true);
+         fail("this should fail");
+      }
+      catch(InvalidSelectorException e)
+      {
+         // OK
+      }
+   }
+   
+   // Package protected ---------------------------------------------
+
+   // Protected -----------------------------------------------------
+
+   // Private -------------------------------------------------------
+
+   // Inner classes -------------------------------------------------
+
+}

Deleted: trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriptionTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriptionTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/DurableSubscriptionTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -1,473 +0,0 @@
-/*
-  * 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.
-  */
-package org.jboss.test.messaging.jms;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.DeliveryMode;
-import javax.jms.InvalidDestinationException;
-import javax.jms.InvalidSelectorException;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-import javax.management.ObjectName;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
-
-/**
- * Tests focused on durable subscription behavior. More durable subscription tests can be found in
- * MessageConsumerTest.
- *
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- *
- * $Id: DurableSubscriberTest.java 1273 2006-09-10 11:53:54Z timfox $
- */
-public class DurableSubscriptionTest extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-
-   // Static --------------------------------------------------------
-
-   // Attributes ----------------------------------------------------
-
-   protected InitialContext ic;
-
-   // Constructors --------------------------------------------------
-
-   public DurableSubscriptionTest(String name)
-   {
-      super(name);
-   }
-
-   // Public --------------------------------------------------------
-
-   public void setUp() throws Exception
-   {
-      super.setUp();
-
-      ServerManagement.start("all");
-            
-      ServerManagement.undeployTopic("Topic");
-      ServerManagement.deployTopic("Topic");
-
-      ic = new InitialContext(ServerManagement.getJNDIEnvironment());
-
-      log.debug("setup done");
-   }
-
-   public void tearDown() throws Exception
-   {
-      log.debug("starting tear down");
-
-      ic.close();
-
-      ServerManagement.undeployTopic("Topic");
-        
-      super.tearDown();
-   }
-
-   public void testSimplestDurableSubscription() throws Exception
-   {
-      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-      Topic topic = (Topic)ic.lookup("/topic/Topic");
-      Connection conn = cf.createConnection();
-
-      conn.setClientID("brookeburke");
-
-      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      MessageProducer prod = s.createProducer(topic);
-      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
-
-      s.createDurableSubscriber(topic, "monicabelucci");
-      
-      ObjectName destObjectName = 
-         new ObjectName("jboss.messaging.destination:service=Topic,name=Topic");
-      String text = (String)ServerManagement.invoke(destObjectName, "listSubscriptionsAsText", null, null);
-       
-      assertTrue(text.indexOf("monicabelucci") != -1);
-
-      prod.send(s.createTextMessage("k"));
-
-      conn.close();
-
-      text = (String)ServerManagement.invoke(destObjectName, "listSubscriptionsAsText", null, null);
-      
-      assertTrue(text.indexOf("monicabelucci") != -1);
-
-      conn = cf.createConnection();
-      conn.setClientID("brookeburke");
-
-      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-      MessageConsumer durable = s.createDurableSubscriber(topic, "monicabelucci");
-
-      conn.start();
-
-      TextMessage tm = (TextMessage)durable.receive();
-      assertEquals("k", tm.getText());
-
-      Message m = durable.receive(1000);
-      assertNull(m);
-   }
-
-   /**
-    * JMS 1.1 6.11.1: A client can change an existing durable subscription by creating a durable
-    * TopicSubscriber with the same name and a new topic and/or message selector, or NoLocal
-    * attribute. Changing a durable subscription is equivalent to deleting and recreating it.
-    *
-    * Test with a different topic (a redeployed topic is a different topic).
-    */
-   public void testDurableSubscriptionOnNewTopic() throws Exception
-   {
-      ServerManagement.deployTopic("CompletelyNewTopic");
-
-      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-      Topic topic = (Topic)ic.lookup("/topic/CompletelyNewTopic");
-      Connection conn = cf.createConnection();
-
-      conn.setClientID("brookeburke");
-
-      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      MessageProducer prod = s.createProducer(topic);
-      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
-
-      s.createDurableSubscriber(topic, "monicabelucci");
-
-      prod.send(s.createTextMessage("one"));
-
-      conn.close();
-
-      ServerManagement.deployTopic("CompletelyNewTopic2");
-
-      Topic topic2 = (Topic)ic.lookup("/topic/CompletelyNewTopic2");
-      conn = cf.createConnection();
-
-      conn.setClientID("brookeburke");
-
-      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      MessageConsumer durable = s.createDurableSubscriber(topic2, "monicabelucci");
-
-      conn.start();
-
-      Message m = durable.receive(1000);
-      assertNull(m);
-
-      ServerManagement.undeployTopic("CompletelyNewTopic");
-      ServerManagement.undeployTopic("CompletelyNewTopic2");
-   }
-
-   /**
-    * JMS 1.1 6.11.1: A client can change an existing durable subscription by creating a durable
-    * TopicSubscriber with the same name and a new topic and/or message selector, or NoLocal
-    * attribute. Changing a durable subscription is equivalent to deleting and recreating it.
-    *
-    * Test with a different selector.
-    */
-   public void testDurableSubscriptionDifferentSelector() throws Exception
-   {
-      ServerManagement.deployTopic("CompletelyNewTopic2");
-      
-      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-      Topic topic = (Topic)ic.lookup("/topic/Topic");
-      Connection conn = cf.createConnection();
-
-      conn.setClientID("brookeburke");
-
-      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      MessageProducer prod = s.createProducer(topic);
-      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
-
-      
-      //fails here
-      MessageConsumer durable =
-         s.createDurableSubscriber(topic,
-                                   "monicabelucci",
-                                   "color = 'red' AND shape = 'square'",
-                                   false);
-
-      TextMessage tm = s.createTextMessage("A red square message");
-      tm.setStringProperty("color", "red");
-      tm.setStringProperty("shape", "square");
-      prod.send(tm);
-
-      conn.start();
-
-      TextMessage rm = (TextMessage)durable.receive(5000);
-      assertEquals("A red square message", rm.getText());
-
-      tm = s.createTextMessage("Another red square message");
-      tm.setStringProperty("color", "red");
-      tm.setStringProperty("shape", "square");
-      prod.send(tm);
-
-      // TODO: when subscriptions/durable subscription will be registered as MBean, use the JMX
-      //       interface to make sure the 'another red square message' is maintained by the
-      //       durable subascription
-      //       http://jira.jboss.org/jira/browse/JBMESSAGING-217
-
-      conn.close();
-
-      conn = cf.createConnection();
-
-      conn.setClientID("brookeburke");
-
-      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-      // modify the selector
-      durable = s.createDurableSubscriber(topic,
-                                          "monicabelucci",
-                                          "color = 'red'",
-                                          false);
-
-      conn.start();
-
-      Message m = durable.receive(1000);
-
-      // the durable subscription is destroyed and re-created. The red square message stored by
-      // the previous durable subscription is lost and (hopefully) garbage collected.
-      assertNull(m);
-      
-      ServerManagement.undeployTopic("CompletelyNewTopic2");
-   }
-
-   /**
-    * JMS 1.1 6.11.1: A client can change an existing durable subscription by creating a durable
-    * TopicSubscriber with the same name and a new topic and/or message selector, or NoLocal
-    * attribute. Changing a durable subscription is equivalent to deleting and recreating it.
-    *
-    * Test with a different noLocal flag.
-    */
-   public void testDurableSubscriptionDifferentNoLocal() throws Exception
-   {
-      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-      Topic topic = (Topic)ic.lookup("/topic/Topic");
-
-      Connection conn = cf.createConnection();
-      conn.setClientID("ID0");
-
-      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      MessageProducer prod = s.createProducer(topic);
-      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
-
-      MessageConsumer durable = s.createDurableSubscriber(topic, "mySubscription", null, false);
-
-      TextMessage tm = null;
-      tm = s.createTextMessage("Message One");
-      prod.send(tm);
-      tm = s.createTextMessage("Message Two");
-      prod.send(tm);
-
-
-      conn.start();
-
-      TextMessage rm = (TextMessage)durable.receive(5000);
-      assertEquals("Message One", rm.getText());
-
-      // TODO: when subscriptions/durable subscription will be registered as MBean, use the JMX
-      //       interface to make sure the 'another red square message' is maintained by the
-      //       durable subascription
-
-      conn.close();
-
-      conn = cf.createConnection();
-      conn.setClientID("ID0");
-      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-      // modify the nolocal flag
-      durable = s.createDurableSubscriber(topic, "mySubscription", null, true);
-
-      conn.start();
-
-      Message m = durable.receive(1000);
-
-      // the durable subscription is destroyed and re-created. "Message Two" stored by the previous
-      // durable subscription is lost and (hopefully) garbage collected.
-      assertNull(m);
-   }
-
-   public void testDurableSubscriptionOnTemporaryTopic() throws Exception
-   {
-      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-      Connection conn = cf.createConnection();
-      conn.setClientID("doesn't actually matter");
-      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      Topic temporaryTopic = s.createTemporaryTopic();
-
-      try
-      {
-         s.createDurableSubscriber(temporaryTopic, "mySubscription");
-         fail("this should throw exception");
-      }
-      catch(InvalidDestinationException e)
-      {
-         // OK
-      }
-   }
-
-   /**
-    * Topic undeployment/redeployment has an activation/deactivation semantic, so undeploying a
-    * topic for which there are durable subscriptions preserves the content of those durable
-    * subscriptions, which can be then access upon topic redeployment.
-    * @throws Exception
-    */
-   public void testDurableSubscriptionOnTopicRedeployment() throws Exception
-   {
-      try
-      {
-         ic.lookup("/topic/TopicToBeRedeployed");
-         fail("should throw exception, topic shouldn't be deployed on the server");
-      }
-      catch(NamingException e)
-      {
-         // OK
-      }
-
-      ServerManagement.deployTopic("TopicToBeRedeployed");
-
-      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-      Topic topic = (Topic)ic.lookup("/topic/TopicToBeRedeployed");
-
-      Connection conn = cf.createConnection();
-      conn.setClientID("brookeburke");
-
-      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      MessageProducer prod = s.createProducer(topic);
-      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
-      MessageConsumer ds = s.createDurableSubscriber(topic, "monicabelucci");
-      conn.start();
-
-      prod.send(s.createTextMessage("one"));
-      prod.send(s.createTextMessage("two"));
-      
-      ServerManagement.undeployTopic("TopicToBeRedeployed");
-      log.debug("topic undeployed");
-
-      try
-      {
-         topic = (Topic)ic.lookup("/topic/TopicToBeRedeployed");
-         fail("should throw exception");
-      }
-      catch(NamingException e)
-      {
-         // OK
-      }
-
-      TextMessage tm = (TextMessage)ds.receive();
-      assertEquals("one", tm.getText());
-      conn.close();
-
-      conn = cf.createConnection();
-      conn.setClientID("brookeburke");
-
-      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-      try
-      {
-         s.createDurableSubscriber(topic, "monicabelucci");
-         fail("should throw exception");
-      }
-      catch(JMSException e)
-      {
-         // OK
-      }
-
-      ServerManagement.deployTopic("TopicToBeRedeployed");
-      log.debug("topic redeployed");
-
-      // since redeployment has an activation semantic, I expect to find the messages there
-
-      topic = (Topic)ic.lookup("/topic/TopicToBeRedeployed");
-      ds =  s.createDurableSubscriber(topic, "monicabelucci");
-      conn.start();
-
-      tm = (TextMessage)ds.receive(1000);
-      assertEquals("two", tm.getText());
-
-      conn.close();
-      ServerManagement.undeployTopic("TopicToBeRedeployed");
-   }
-
-   public void testUnsubscribeDurableSubscription() throws Exception
-   {
-      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-      Topic topic = (Topic)ic.lookup("/topic/Topic");
-
-      Connection conn = cf.createConnection();
-      conn.setClientID("ak47");
-
-      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-      s.createDurableSubscriber(topic, "uzzi");
-      MessageProducer prod = s.createProducer(topic);
-      prod.setDeliveryMode(DeliveryMode.PERSISTENT);
-
-      prod.send(s.createTextMessage("one"));
-
-      log.debug("unsubscribing ...");
-
-      s.unsubscribe("uzzi");
-
-      log.debug("resubscribing ...");
-
-      MessageConsumer ds = s.createDurableSubscriber(topic, "uzzi");
-      conn.start();
-
-      assertNull(ds.receive(1000));
-
-      conn.close();
-   }
-
-   public void testInvalidSelectorException() throws Exception
-   {
-      ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-      Topic topic = (Topic)ic.lookup("/topic/Topic");
-      Connection c = cf.createConnection();
-      c.setClientID("sofiavergara");
-      Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-      try
-      {
-         s.createDurableSubscriber(topic, "mysubscribption", "=TEST 'test'", true);
-         fail("this should fail");
-      }
-      catch(InvalidSelectorException e)
-      {
-         // OK
-      }
-   }
-   
-   // Package protected ---------------------------------------------
-
-   // Protected -----------------------------------------------------
-
-   // Private -------------------------------------------------------
-
-   // Inner classes -------------------------------------------------
-
-}

Copied: trunk/tests/src/org/jboss/test/messaging/jms/JCAWrapperTest.java (from rev 1367, branches/Branch_1_0/tests/src/org/jboss/test/messaging/jms/JCAWrapperTest.java)

Modified: trunk/tests/src/org/jboss/test/messaging/jms/JMSTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/JMSTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/JMSTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -30,7 +30,9 @@
 import javax.jms.Session;
 import javax.jms.TextMessage;
 import javax.jms.Message;
+import javax.jms.MessageListener;
 import javax.naming.InitialContext;
+import javax.management.ObjectName;
 
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.tools.ServerManagement;
@@ -153,7 +155,7 @@
       conn.close();
    }
 
-   public void test_NonPersistent_Transactional() throws Exception
+   public void test_NonPersistent_Transactional_Send() throws Exception
    {
       ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
 
@@ -191,7 +193,7 @@
       conn.close();
    }
 
-   public void test_NonPersistent_NonTransactional_Asynchronous_to_Client() throws Exception
+   public void test_NonPersistent_Transactional_Acknowledgment() throws Exception
    {
       ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
 
@@ -201,6 +203,40 @@
 
       Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
+      MessageProducer prod = session.createProducer(queue);
+      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+      TextMessage m = session.createTextMessage("one");
+      prod.send(m);
+
+      conn.close();
+
+      conn = cf.createConnection();
+
+      session = conn.createSession(true, Session.SESSION_TRANSACTED);
+
+      MessageConsumer cons = session.createConsumer(queue);
+
+      conn.start();
+
+      TextMessage rm = (TextMessage)cons.receive();
+      assertEquals("one", rm.getText());
+
+      session.commit();
+
+      conn.close();
+   }
+
+
+   public void test_Asynchronous_to_Client() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
+
+      Queue queue = (Queue)ic.lookup("/queue/JMSTestQueue");
+
+      Connection conn = cf.createConnection();
+
+      Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
       final MessageConsumer cons = session.createConsumer(queue);
 
       conn.start();
@@ -244,7 +280,91 @@
       conn.close();
    }
 
+   public void test_MessageListener() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
 
+      Queue queue = (Queue)ic.lookup("/queue/JMSTestQueue");
+
+      Connection conn = cf.createConnection();
+
+      Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+      MessageConsumer cons = session.createConsumer(queue);
+
+      final Slot slot = new Slot();
+
+      cons.setMessageListener(new MessageListener()
+      {
+         public void onMessage(Message m)
+         {
+            try
+            {
+               slot.put(m);
+            }
+            catch(InterruptedException e)
+            {
+               log.warn("got InterruptedException", e);
+            }
+         }
+      });
+
+      conn.start();
+
+      MessageProducer prod = session.createProducer(queue);
+      prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
+      TextMessage m = session.createTextMessage("one");
+      prod.send(m);
+
+      TextMessage rm = (TextMessage)slot.poll(5000);
+
+      assertEquals("one", rm.getText());
+
+      conn.close();
+   }
+
+   public void test_ClientAcknowledge() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
+
+      Queue queue = (Queue)ic.lookup("/queue/JMSTestQueue");
+
+      Connection conn = cf.createConnection();
+
+      Session session = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+      MessageProducer p = session.createProducer(queue);
+      p.send(session.createTextMessage("CLACK"));
+
+      MessageConsumer cons = session.createConsumer(queue);
+
+      conn.start();
+
+      TextMessage m = (TextMessage)cons.receive(1000);
+
+      assertEquals("CLACK", m.getText());
+
+      // make sure there's no other message in queue
+      Message m2 = cons.receive(1000);
+      assertNull(m2);
+
+      // make sure the message is still in "delivering" state
+      ObjectName on = new ObjectName("jboss.messaging.destination:service=Queue,name=JMSTestQueue");
+      Integer mc = (Integer)ServerManagement.getAttribute(on, "MessageCount");
+
+      assertEquals(1, mc.intValue());
+
+      m.acknowledge();
+
+      // make sure there's nothing in queue anymore
+      mc = (Integer)ServerManagement.getAttribute(on, "MessageCount");
+
+      assertEquals(0, mc.intValue());
+
+      conn.close();
+   }
+
+
+
    // Package protected ---------------------------------------------
 
    // Protected -----------------------------------------------------

Modified: trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -251,15 +251,15 @@
       
       assertEquals("Your mum", tm2.getText());
       
-      //Don't ack
+      // Don't ack
       
-      //Create another consumer
+      // Create another consumer
       
       Session sessConsume2 = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
       
       MessageConsumer cons2 = sessConsume2.createConsumer(queue);
       
-      //this should cancel message and cause delivery to other consumer
+      // this should cancel message and cause delivery to other consumer
       
       sessConsume1.close();
       

Modified: trunk/tests/src/org/jboss/test/messaging/jms/MiscellaneousTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/MiscellaneousTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/MiscellaneousTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -29,7 +29,11 @@
 import javax.jms.Session;
 import javax.jms.TextMessage;
 import javax.jms.QueueBrowser;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
 import javax.naming.InitialContext;
+import javax.management.ObjectName;
 
 import org.jboss.test.messaging.MessagingTestCase;
 import org.jboss.test.messaging.tools.ServerManagement;
@@ -37,7 +41,7 @@
 import java.util.Enumeration;
 
 /**
- * Various use cases, added here while trying things.
+ * Various use cases, added here while trying things or fixing forum issues.
  *
  * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
  * @version <tt>$Revision$</tt>
@@ -90,6 +94,175 @@
       conn.close();
    }
 
+   /**
+    * Test case for http://jira.jboss.org/jira/browse/JBMESSAGING-542
+    */
+   public void testClosingConsumerFromMessageListener() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
+      Queue queue = (Queue)ic.lookup("/queue/MiscellaneousQueue");
+
+      // load the queue
+
+      Connection c = cf.createConnection();
+      Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = s.createProducer(queue);
+      Message m = s.createMessage();
+      prod.send(m);
+      c.close();
+
+      final Result result = new Result();
+      Connection conn = cf.createConnection();
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      final MessageConsumer cons = s.createConsumer(queue);
+      cons.setMessageListener(new MessageListener()
+      {
+         public void onMessage(Message m)
+         {
+            // close the connection on the same thread that processed the message
+            try
+            {
+               log.debug("attempting close");
+               cons.close();
+               log.debug("consumer closed");
+               result.setSuccess();
+            }
+            catch(Exception e)
+            {
+               result.setFailure(e);
+            }
+         }
+      });
+
+      conn.start();
+
+      // wait for the message to propagate
+      Thread.sleep(3000);
+
+      assertTrue(result.isSuccess());
+      assertNull(result.getFailure());
+
+      // make sure the acknowledgment made it back to the queue
+
+      Integer count = (Integer)ServerManagement.
+         getAttribute(new ObjectName("jboss.messaging.destination:service=Queue,name=MiscellaneousQueue"),
+                      "MessageCount");
+      assertEquals(0, count.intValue());
+   }
+
+   /**
+    * Test case for http://jira.jboss.org/jira/browse/JBMESSAGING-542
+    */
+   public void testClosingSessionFromMessageListener() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
+      Queue queue = (Queue)ic.lookup("/queue/MiscellaneousQueue");
+
+      // load the queue
+
+      Connection c = cf.createConnection();
+      Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = s.createProducer(queue);
+      Message m = s.createMessage();
+      prod.send(m);
+      c.close();
+
+      final Result result = new Result();
+      Connection conn = cf.createConnection();
+      final Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageConsumer cons = session.createConsumer(queue);
+      cons.setMessageListener(new MessageListener()
+      {
+         public void onMessage(Message m)
+         {
+            // close the connection on the same thread that processed the message
+            try
+            {
+               log.debug("attempting close");
+               session.close();
+               log.debug("session closed");
+               result.setSuccess();
+            }
+            catch(Exception e)
+            {
+               result.setFailure(e);
+            }
+         }
+      });
+
+      conn.start();
+
+      // wait for the message to propagate
+      Thread.sleep(3000);
+
+      assertTrue(result.isSuccess());
+      assertNull(result.getFailure());
+
+      // make sure the acknowledgment made it back to the queue
+
+      Integer count = (Integer)ServerManagement.
+         getAttribute(new ObjectName("jboss.messaging.destination:service=Queue,name=MiscellaneousQueue"),
+                      "MessageCount");
+      assertEquals(0, count.intValue());
+
+   }
+
+   /**
+    * Test case for http://jira.jboss.org/jira/browse/JBMESSAGING-542
+    */
+   public void testClosingConnectionFromMessageListener() throws Exception
+   {
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
+      Queue queue = (Queue)ic.lookup("/queue/MiscellaneousQueue");
+
+      // load the queue
+
+      Connection c = cf.createConnection();
+      Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer prod = s.createProducer(queue);
+      Message m = s.createMessage();
+      prod.send(m);
+      c.close();
+
+      final Result result = new Result();
+      final Connection conn = cf.createConnection();
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageConsumer cons = s.createConsumer(queue);
+      cons.setMessageListener(new MessageListener()
+      {
+         public void onMessage(Message m)
+         {
+            // close the connection on the same thread that processed the message
+            try
+            {
+               log.debug("attempting close");
+               conn.close();
+               log.debug("conn closed");
+               result.setSuccess();
+            }
+            catch(Exception e)
+            {
+               result.setFailure(e);
+            }
+         }
+      });
+
+      conn.start();
+
+      // wait for the message to propagate
+      Thread.sleep(3000);
+
+      assertTrue(result.isSuccess());
+      assertNull(result.getFailure());
+
+      // make sure the acknowledgment made it back to the queue
+
+      Integer count = (Integer)ServerManagement.
+         getAttribute(new ObjectName("jboss.messaging.destination:service=Queue,name=MiscellaneousQueue"),
+                      "MessageCount");
+      assertEquals(0, count.intValue());
+   }
+
    // Package protected ---------------------------------------------
 
    // Protected -----------------------------------------------------
@@ -122,4 +295,36 @@
 
    // Inner classes -------------------------------------------------
 
+   private class Result
+   {
+      private boolean success;
+      private Exception e;
+
+      public Result()
+      {
+         success = false;
+         e = null;
+      }
+
+      public synchronized void setSuccess()
+      {
+         success = true;
+      }
+
+      public synchronized boolean isSuccess()
+      {
+         return success;
+      }
+
+      public synchronized void setFailure(Exception e)
+      {
+         this.e = e;
+      }
+
+      public synchronized Exception getFailure()
+      {
+         return e;
+      }
+   }
+
 }

Modified: trunk/tests/src/org/jboss/test/messaging/jms/SessionTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/SessionTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/SessionTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -38,6 +38,7 @@
 import javax.jms.XAConnection;
 import javax.jms.XASession;
 import javax.naming.InitialContext;
+import javax.management.ObjectName;
 
 import org.jboss.jms.client.JBossConnectionFactory;
 import org.jboss.jms.client.JBossSession;
@@ -464,7 +465,81 @@
    }
 
 
+   public void testCloseNoClientAcknowledgment() throws Exception
+   {
+      // send a message to the queue
 
+      Connection conn = cf.createConnection();
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      s.createProducer(queue).send(s.createTextMessage("wont_ack"));
+      conn.close();
+
+      conn = cf.createConnection();
+      s = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+      conn.start();
+
+      TextMessage m = (TextMessage)s.createConsumer(queue).receive(1000);
+
+      assertEquals("wont_ack", m.getText());
+
+      // Do NOT ACK
+
+      s.close(); // this shouldn cancel the delivery
+
+      // get the message again
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      m = (TextMessage)s.createConsumer(queue).receive(1000);
+
+      assertEquals("wont_ack", m.getText());
+
+      conn.close();
+   }
+
+   public void testCloseInTransaction() throws Exception
+   {
+      // send a message to the queue
+
+      Connection conn = cf.createConnection();
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      s.createProducer(queue).send(s.createTextMessage("bex"));
+      conn.close();
+
+      conn = cf.createConnection();
+      Session session = conn.createSession(true, -1);
+      conn.start();
+
+      TextMessage m = (TextMessage)session.createConsumer(queue).receive(1000);
+
+      assertEquals("bex", m.getText());
+
+      // make sure the acknowledment hasn't been sent to the channel
+      ObjectName on = new ObjectName("jboss.messaging.destination:service=Queue,name=TestQueue");
+      Integer mc = (Integer)ServerManagement.getAttribute(on, "MessageCount");
+
+      assertEquals(1, mc.intValue());
+
+      // close the session
+      session.close();
+
+      // JMS 1.1 4.4.1: "Closing a transacted session must roll back its transaction in progress"
+
+      mc = (Integer)ServerManagement.getAttribute(on, "MessageCount");
+      assertEquals(1, mc.intValue());
+
+      conn.close();
+
+      // make sure I can still get the right message
+
+      conn = cf.createConnection();
+      s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      conn.start();
+      TextMessage rm = (TextMessage)s.createConsumer(queue).receive(1000);
+
+      assertEquals("bex", m.getText());
+
+      conn.close();
+   }
+
    // Package protected ---------------------------------------------
    
    // Protected -----------------------------------------------------

Modified: trunk/tests/src/org/jboss/test/messaging/jms/TransactedSessionTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/TransactedSessionTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/TransactedSessionTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -29,6 +29,7 @@
 import javax.jms.Session;
 import javax.jms.TextMessage;
 import javax.naming.InitialContext;
+import javax.management.ObjectName;
 
 import org.jboss.jms.client.JBossConnectionFactory;
 import org.jboss.test.messaging.MessagingTestCase;
@@ -93,6 +94,42 @@
    
    
    // Public --------------------------------------------------------
+
+
+   public void testSimpleRollback() throws Exception
+   {
+      // send a message
+      Connection conn = cf.createConnection();
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      s.createProducer(queue).send(s.createTextMessage("one"));
+
+      log.debug("message sent");
+
+      s.close();
+
+      s = conn.createSession(true, Session.SESSION_TRANSACTED);
+      MessageConsumer c = s.createConsumer(queue);
+      conn.start();
+      Message m = c.receive();
+
+      assertEquals("one", ((TextMessage)m).getText());
+      assertFalse(m.getJMSRedelivered());
+      assertEquals(1, m.getIntProperty("JMSXDeliveryCount"));
+
+      s.rollback();
+
+      // get the message again
+      m = c.receive();
+      assertTrue(m.getJMSRedelivered());
+      assertEquals(2, m.getIntProperty("JMSXDeliveryCount"));
+
+      conn.close();
+
+      ObjectName on = new ObjectName("jboss.messaging.destination:service=Queue,name=Queue");
+      Integer i = (Integer)ServerManagement.getAttribute(on, "MessageCount");
+
+      assertEquals(1, i.intValue());
+   }
    
    public void testRedeliveredFlagTopic() throws Exception
    {
@@ -536,7 +573,9 @@
          TextMessage tm = (TextMessage)cons.receive();
 
          assertEquals("a message", tm.getText());
+
          assertFalse(tm.getJMSRedelivered());
+         assertEquals(1, tm.getIntProperty("JMSXDeliveryCount"));
 
          sess.rollback();
          sess.close();
@@ -548,63 +587,9 @@
          tm = (TextMessage)cons.receive();
 
          assertEquals("a message", tm.getText());
-         assertTrue(tm.getJMSRedelivered());
-      }
-      finally
-      {
-         if (conn != null)
-         {
-            conn.close();
-         }
-      }
-   }
 
-   /**
-    * Make sure redelivered flag is set on redelivery via rollback, different setup: we don't close
-    * the rolled back session and we receive the message whose acknowledgment was cancelled on a new
-    * session.
-    *
-    * TODO: Is this test semantically correct.
-    */
-   public void testRedeliveredQueue3() throws Exception
-   {
-      Connection conn = null;
-
-      try
-      {
-         conn = cf.createConnection();
-
-         Session sendSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-         MessageProducer prod = sendSession.createProducer(queue);
-         prod.send(sendSession.createTextMessage("a message"));
-
-         log.debug("Message was sent to the queue");
-
-         conn.close();
-
-         conn = cf.createConnection();
-         Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
-
-         MessageConsumer cons = sess.createConsumer(queue);
-
-         conn.start();
-
-         TextMessage tm = (TextMessage)cons.receive();
-
-         assertEquals("a message", tm.getText());
-         assertFalse(tm.getJMSRedelivered());
-
-         sess.rollback();
-
-         Session sess2 = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
-         cons = sess2.createConsumer(queue);
-
-         tm = (TextMessage)cons.receive(3000);
-
-         assertEquals("a message", tm.getText());
          assertTrue(tm.getJMSRedelivered());
+         assertEquals(2, tm.getIntProperty("JMSXDeliveryCount"));
       }
       finally
       {
@@ -615,7 +600,6 @@
       }
    }
 
-
    public void testReceivedRollbackQueue() throws Exception
    {
       Connection conn = cf.createConnection();

Modified: trunk/tests/src/org/jboss/test/messaging/jms/WireFormatTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/WireFormatTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/WireFormatTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -265,7 +265,7 @@
          
          long messageID = 123456;
          int consumerID = 65432;
-         AckInfo ack = new AckInfo(messageID, consumerID);
+         AckInfo ack = new AckInfo(messageID, consumerID, -1);
          
          Object[] args = new Object[] { ack };
          
@@ -355,9 +355,9 @@
          
          mi.getMetaData().addMetaData(Dispatcher.DISPATCHER, Dispatcher.OID, new Integer(objectId));   
          
-         AckInfo ackA = new AckInfo(1524, 71627);
-         AckInfo ackB = new AckInfo(987987, 45354);
-         AckInfo ackC = new AckInfo(32423, 4533);
+         AckInfo ackA = new AckInfo(1524, 71627, -1);
+         AckInfo ackB = new AckInfo(987987, 45354, -1);
+         AckInfo ackC = new AckInfo(32423, 4533, -1);
          
          List acks = new ArrayList();
          acks.add(ackA);
@@ -733,7 +733,7 @@
          JBossMessage m = new JBossMessage(123);
          MessageTest.configureMessage(m);
          
-         AckInfo info = new AckInfo(123, 456);
+         AckInfo info = new AckInfo(123, 456, -1);
          
          TxState state = new TxState();
          state.getMessages().add(m);
@@ -852,8 +852,8 @@
          
          List ids = new ArrayList();
          
-         AckInfo ack1 = new AckInfo(1254, 78123);
-         AckInfo ack2 = new AckInfo(786, 8979);
+         AckInfo ack1 = new AckInfo(1254, 78123, -1);
+         AckInfo ack2 = new AckInfo(786, 8979, -1);
          ids.add(ack1);
          ids.add(ack2);
          

Deleted: trunk/tests/src/org/jboss/test/messaging/jms/XATransactionTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/XATransactionTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/XATransactionTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -1,139 +0,0 @@
-/*
-  * 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.
-  */
-package org.jboss.test.messaging.jms;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.Message;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import javax.naming.InitialContext;
-import javax.transaction.Transaction;
-import javax.transaction.UserTransaction;
-
-import org.jboss.test.messaging.MessagingTestCase;
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.tm.TransactionManagerLocator;
-
-/**
- * @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
- *
- * $Id$
- */
-public class XATransactionTest extends MessagingTestCase
-{
-   // Constants -----------------------------------------------------
-   
-   // Static --------------------------------------------------------
-   
-   // Attributes ----------------------------------------------------
-
-   protected InitialContext ic;
-   protected Queue queue;
-
-   // Constructors --------------------------------------------------
-   
-   public XATransactionTest(String name)
-   {
-      super(name);
-   }
-   
-   // Public --------------------------------------------------------
-
-   public void testSimpleTransactedSend() throws Exception
-   {
-      Transaction suspended = TransactionManagerLocator.getInstance().locate().suspend();
-      
-      try
-      {
-         
-         ConnectionFactory mcf = (ConnectionFactory)ic.lookup("java:/JCAConnectionFactory");
-         Connection conn = mcf.createConnection();
-         conn.start();
-   
-         UserTransaction ut = ServerManagement.getUserTransaction();
-   
-         ut.begin();
-   
-         Session s = conn.createSession(true, Session.SESSION_TRANSACTED);
-         MessageProducer p = s.createProducer(queue);
-         Message m = s.createTextMessage("one");
-   
-         p.send(m);
-   
-         ut.commit();
-   
-         conn.close();
-   
-         ConnectionFactory cf = (ConnectionFactory)ic.lookup("ConnectionFactory");
-         conn = cf.createConnection();
-         s = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-         conn.start();
-   
-         TextMessage rm = (TextMessage)s.createConsumer(queue).receive(500);
-   
-         assertEquals("one", rm.getText());
-      }
-      finally
-      {
-         
-         if (suspended != null)
-         {
-            TransactionManagerLocator.getInstance().locate().resume(suspended);
-         }
-      }
-   }
-
-   // Package protected ---------------------------------------------
-   
-   // Protected -----------------------------------------------------
-
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-      ServerManagement.start("all");
-
-      ic = new InitialContext(ServerManagement.getJNDIEnvironment());
-
-      ServerManagement.deployQueue("UserTransactionTestQueue");
-      queue = (Queue)ic.lookup("/queue/UserTransactionTestQueue");
-      drainDestination((ConnectionFactory)ic.lookup("/ConnectionFactory"), queue);
-
-      log.debug("setup done");
-   }
-
-   protected void tearDown() throws Exception
-   {
-      ServerManagement.undeployQueue("UserTransactionTestQueue");
-      ic.close();
-      super.tearDown();
-   }
-
-   // Private -------------------------------------------------------
-   
-   // Inner classes -------------------------------------------------
-   
-}
-
-

Modified: trunk/tests/src/org/jboss/test/messaging/jms/crash/ClientCrashTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/crash/ClientCrashTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/crash/ClientCrashTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -41,7 +41,7 @@
  * @author <a href="tim.fox at jboss.com">Tim Fox</a>
  * @version 1.1
  *
- * ClientCrashTest.java,v 1.1 2006/02/21 08:22:28 timfox Exp
+ * $Id$
  */
 public class ClientCrashTest extends MessagingTestCase
 {
@@ -83,6 +83,7 @@
       localServer.setAttribute(ServiceContainer.REMOTING_OBJECT_NAME, "LeasePeriod", "3000");
        
       localServer.deployQueue("Queue", null);
+      localServer.deployTopic("Topic", null);
           
       // Connect to the remote server, but don't start a servicecontainer on it. We are only using
       // the remote server to open a client connection to the local server.
@@ -130,7 +131,6 @@
       assertFalse(cm.containsSession(remotingSessionId));            
    }
    
-   
    // Package protected ---------------------------------------------
    
    // Protected -----------------------------------------------------

Modified: trunk/tests/src/org/jboss/test/messaging/jms/crash/ClientCrashTwoConnectionsTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/crash/ClientCrashTwoConnectionsTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/crash/ClientCrashTwoConnectionsTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -1,3 +1,4 @@
+<<<<<<< .working
 /*
   * JBoss, Home of Professional Open Source
   * Copyright 2005, JBoss Inc., and individual contributors as indicated
@@ -147,3 +148,159 @@
    // Inner classes -------------------------------------------------
 
 }
+=======
+/*
+  * 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.
+  */
+package org.jboss.test.messaging.jms.crash;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Topic;
+import javax.naming.InitialContext;
+
+import org.jboss.jms.server.ConnectionManager;
+import org.jboss.jms.server.connectionmanager.SimpleConnectionManager;
+import org.jboss.logging.Logger;
+import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.jms.CreateTwoClientOnServerCommand;
+import org.jboss.test.messaging.tools.ServerManagement;
+import org.jboss.test.messaging.tools.jmx.ServiceContainer;
+import org.jboss.test.messaging.tools.jmx.rmi.LocalTestServer;
+import org.jboss.test.messaging.tools.jmx.rmi.Server;
+import org.jboss.test.messaging.tools.jndi.InVMInitialContextFactory;
+
+/**
+ * 
+ * A ClientCrashTest.
+ * 
+ * @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="clebert.suconic at jboss.com">Clebert Suconic</a>
+ * @version 1.1
+ *
+ * $Id$
+ */
+public class ClientCrashTwoConnectionsTest extends MessagingTestCase
+{
+   // Constants -----------------------------------------------------
+
+   // Static --------------------------------------------------------
+   
+   private static final Logger log = Logger.getLogger(ClientCrashTwoConnectionsTest.class);
+   
+   // Attributes ----------------------------------------------------
+   
+   protected Server localServer;
+   
+   protected Server remoteServer;
+
+   // Constructors --------------------------------------------------
+
+   public ClientCrashTwoConnectionsTest(String name)
+   {
+      super(name);
+   }
+
+   // Public --------------------------------------------------------
+
+   public void setUp() throws Exception
+   {
+      super.setUp();
+      
+      // Start the local server
+      localServer = new LocalTestServer();
+      
+      // Start all the services locally
+      localServer.start("all");
+
+
+      // This crash test is relying on a precise value of LeaseInterval, so we don't rely on
+      // the default, whatever that is ...
+
+      localServer.setAttribute(ServiceContainer.REMOTING_OBJECT_NAME, "LeasePeriod", "3000");
+       
+      localServer.deployQueue("Queue", null);
+      localServer.deployTopic("Topic", null);
+          
+      // Connect to the remote server, but don't start a servicecontainer on it. We are only using
+      // the remote server to open a client connection to the local server.
+      ServerManagement.create();
+          
+      remoteServer = ServerManagement.getServer();
+
+      log.debug("setup done");
+   }
+
+   public void tearDown() throws Exception
+   {       
+      localServer.stop();
+   }
+      
+   /**
+    * Test that when a remote jms client crashes, server side resources for connections are
+    * cleaned-up.
+    */
+   public void testClientCrashWithTwoConnections() throws Exception
+   {
+      InitialContext ic = new InitialContext(InVMInitialContextFactory.getJNDIEnvironment());
+      Topic topic = (Topic)ic.lookup("/topic/Topic");
+      
+      ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
+      
+      CreateTwoClientOnServerCommand command = new CreateTwoClientOnServerCommand(cf, topic, true);
+      
+      String remotingSessionId[] = (String[])remoteServer.executeCommand(command);
+      
+      ConnectionManager cm = localServer.getServerPeer().getConnectionManager();
+            
+      log.info("server(0) = " + remotingSessionId[0]);
+      log.info("server(1) = " + remotingSessionId[1]);
+      log.info("we have = " + ((SimpleConnectionManager)cm).getClients().size() + " clients registered on SimpleconnectionManager");
+      
+      // Now we should have a client connection from the remote server to the local server
+      remoteServer.exit();
+      log.info("killed remote server");
+        
+      // Wait for connection resources to be cleared up
+      Thread.sleep(25000);
+           
+      // See if we still have a connection with this id
+      
+      //Connection state shouldn't have been cleared up by now
+      assertFalse(cm.containsSession(remotingSessionId[0]));            
+      assertFalse(cm.containsSession(remotingSessionId[1]));            
+      
+      log.info("Servers = " + ((SimpleConnectionManager)cm).getClients().size());
+      
+      assertEquals(0,((SimpleConnectionManager)cm).getClients().size());
+   }
+   
+   
+   // Package protected ---------------------------------------------
+   
+   // Protected -----------------------------------------------------
+   
+   // Private -------------------------------------------------------
+   
+  
+   // Inner classes -------------------------------------------------
+
+}
+>>>>>>> .merge-right.r1367

Modified: trunk/tests/src/org/jboss/test/messaging/jms/message/JMSXDeliveryCountTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/message/JMSXDeliveryCountTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/message/JMSXDeliveryCountTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -93,7 +93,37 @@
       super.tearDown();
    }
 
+   public void testSimpleJMSXDeliverCount() throws Exception
+   {
+      Connection conn = cf.createConnection();
+      Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+      MessageProducer p = s.createProducer(queue);
+      p.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
 
+      p.send(s.createTextMessage("xoxo"));
+
+      s.close();
+
+      s = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+      MessageConsumer c = s.createConsumer(queue);
+
+      conn.start();
+
+      TextMessage tm = (TextMessage)c.receive(1000);
+
+      assertEquals("xoxo", tm.getText());
+      assertEquals(1, tm.getIntProperty("JMSXDeliveryCount"));
+
+      s.recover();
+
+      tm = (TextMessage)c.receive(1000);
+
+      assertEquals("xoxo", tm.getText());
+      assertEquals(2, tm.getIntProperty("JMSXDeliveryCount"));
+
+      conn.close();
+   }
+
    public void testRedeliveryOnQueue() throws Exception
    {
       Connection conn = cf.createConnection();
@@ -128,7 +158,7 @@
             TextMessage tm = (TextMessage)cons.receive(3000);
             assertNotNull(tm);
             assertEquals("testing" + i, tm.getText());
-            assertEquals(j, tm.getIntProperty("JMSXDeliveryCount"));
+            assertEquals(j + 1, tm.getIntProperty("JMSXDeliveryCount"));
          }
          sess2.recover();
       }
@@ -239,9 +269,10 @@
                      failed = true;
                   }
 
-                  if (tm.getIntProperty("JMSXDeliveryCount") != j)
+                  if (tm.getIntProperty("JMSXDeliveryCount") != (j + 1))
                   {
-                     log.error("Delivery count not expected value:" + j + " actual:" + tm.getIntProperty("JMSXDeliveryCount"));;
+                     log.error("Delivery count not expected value:" + (j + 1) +
+                               " actual:" + tm.getIntProperty("JMSXDeliveryCount"));;
                      failed = true;
                   }
                }

Modified: trunk/tests/src/org/jboss/test/messaging/jms/server/destination/QueueManagementTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/server/destination/QueueManagementTest.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/jms/server/destination/QueueManagementTest.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -234,6 +234,7 @@
       Connection conn = null;
 
       int fullSize = 10;
+      int MESSAGE_COUNT = 100;
 
       ServerManagement.deployQueue("QueueMessageCount2", fullSize, fullSize / 2, fullSize / 2 - 1);
 
@@ -249,18 +250,38 @@
          MessageProducer prod = session.createProducer(queue);
          prod.setDeliveryMode(DeliveryMode.PERSISTENT);
 
-         // Send 20 message to the queue
+         // Send all messages to the queue and check messageCount after each send
 
-         for(int i = 0; i < 20; i++)
+         for(int i = 0; i < MESSAGE_COUNT; i++)
          {
             TextMessage m = session.createTextMessage("message" + i);
             prod.send(m);
+
+            int mc = ((Integer)ServerManagement.
+               getAttribute(destObjectName, "MessageCount")).intValue();
+
+            assertEquals(i + 1, mc);
          }
 
-         int mc =
-            ((Integer)ServerManagement.getAttribute(destObjectName, "MessageCount")).intValue();
+         // receive messages from queue one by one and check messageCount after each receive
 
-         assertEquals(20, mc);
+         MessageConsumer cons = session.createConsumer(queue);
+         conn.start();
+
+         int receivedCount = 0;
+
+         while((cons.receive(2000)) != null)
+         {
+            receivedCount++;
+
+            int mc = ((Integer)ServerManagement.
+               getAttribute(destObjectName, "MessageCount")).intValue();
+
+            assertEquals(MESSAGE_COUNT - receivedCount, mc);
+         }
+
+         assertEquals(MESSAGE_COUNT, receivedCount);
+
       }
       finally
       {

Modified: trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java	2006-09-26 20:22:20 UTC (rev 1367)
+++ trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java	2006-09-27 07:55:32 UTC (rev 1368)
@@ -124,18 +124,6 @@
       throw new IllegalStateException("The RMI server doesn't seem to be started. " +
                                       "Start it and re-run the test.");
 
-//      // start the service container and the JMS server in a different VM
-//      vmStarter = new Thread(new VMStarter(), "External VM Starter Thread");
-//      vmStarter.setDaemon(true);
-//      vmStarter.start();
-//
-//      server = acquireRemote(RMI_SERVER_LOOKUP_RETRIES);
-//
-//      if (server == null)
-//      {
-//         throw new IllegalStateException("Cannot find remote server " +
-//                                         TestServer.RMI_SERVER_NAME + " in registry");
-//      }
    }
 
    public static synchronized void start(String config) throws Exception




More information about the jboss-cvs-commits mailing list