1 /*
2  * Copyright 2002-2011 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.jms.connection;
18 
19 import javax.jms.Connection;
20 import javax.jms.ConnectionFactory;
21 import javax.jms.ExceptionListener;
22 import javax.jms.JMSException;
23 import javax.jms.QueueConnection;
24 import javax.jms.QueueConnectionFactory;
25 import javax.jms.QueueSession;
26 import javax.jms.Session;
27 import javax.jms.TopicConnection;
28 import javax.jms.TopicConnectionFactory;
29 import javax.jms.TopicSession;
30 
31 import junit.framework.TestCase;
32 import org.easymock.MockControl;
33 
34 /**
35  * @author Juergen Hoeller
36  * @since 26.07.2004
37  */
38 public class SingleConnectionFactoryTests extends TestCase {
39 
testWithConnection()40 	public void testWithConnection() throws JMSException {
41 		MockControl conControl = MockControl.createControl(Connection.class);
42 		Connection con = (Connection) conControl.getMock();
43 
44 		con.start();
45 		conControl.setVoidCallable(1);
46 		con.stop();
47 		conControl.setVoidCallable(1);
48 		con.close();
49 		conControl.setVoidCallable(1);
50 
51 		conControl.replay();
52 
53 		SingleConnectionFactory scf = new SingleConnectionFactory(con);
54 		Connection con1 = scf.createConnection();
55 		con1.start();
56 		con1.stop();  // should be ignored
57 		con1.close();  // should be ignored
58 		Connection con2 = scf.createConnection();
59 		con2.start();  // should be ignored
60 		con2.stop();  // should be ignored
61 		con2.close();  // should be ignored
62 		scf.destroy();  // should trigger actual close
63 
64 		conControl.verify();
65 	}
66 
testWithQueueConnection()67 	public void testWithQueueConnection() throws JMSException {
68 		MockControl conControl = MockControl.createControl(QueueConnection.class);
69 		Connection con = (QueueConnection) conControl.getMock();
70 
71 		con.start();
72 		conControl.setVoidCallable(1);
73 		con.stop();
74 		conControl.setVoidCallable(1);
75 		con.close();
76 		conControl.setVoidCallable(1);
77 
78 		conControl.replay();
79 
80 		SingleConnectionFactory scf = new SingleConnectionFactory(con);
81 		QueueConnection con1 = scf.createQueueConnection();
82 		con1.start();
83 		con1.stop();  // should be ignored
84 		con1.close();  // should be ignored
85 		QueueConnection con2 = scf.createQueueConnection();
86 		con2.start();
87 		con2.stop();  // should be ignored
88 		con2.close();  // should be ignored
89 		scf.destroy();  // should trigger actual close
90 
91 		conControl.verify();
92 	}
93 
testWithTopicConnection()94 	public void testWithTopicConnection() throws JMSException {
95 		MockControl conControl = MockControl.createControl(TopicConnection.class);
96 		Connection con = (TopicConnection) conControl.getMock();
97 
98 		con.start();
99 		conControl.setVoidCallable(1);
100 		con.stop();
101 		conControl.setVoidCallable(1);
102 		con.close();
103 		conControl.setVoidCallable(1);
104 
105 		conControl.replay();
106 
107 		SingleConnectionFactory scf = new SingleConnectionFactory(con);
108 		TopicConnection con1 = scf.createTopicConnection();
109 		con1.start();
110 		con1.stop();  // should be ignored
111 		con1.close();  // should be ignored
112 		TopicConnection con2 = scf.createTopicConnection();
113 		con2.start();
114 		con2.stop();  // should be ignored
115 		con2.close();  // should be ignored
116 		scf.destroy();  // should trigger actual close
117 
118 		conControl.verify();
119 	}
120 
testWithConnectionFactory()121 	public void testWithConnectionFactory() throws JMSException {
122 		MockControl cfControl = MockControl.createControl(ConnectionFactory.class);
123 		ConnectionFactory cf = (ConnectionFactory) cfControl.getMock();
124 		MockControl conControl = MockControl.createControl(Connection.class);
125 		Connection con = (Connection) conControl.getMock();
126 
127 		cf.createConnection();
128 		cfControl.setReturnValue(con, 1);
129 		con.start();
130 		conControl.setVoidCallable(1);
131 		con.stop();
132 		conControl.setVoidCallable(1);
133 		con.close();
134 		conControl.setVoidCallable(1);
135 
136 		cfControl.replay();
137 		conControl.replay();
138 
139 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
140 		Connection con1 = scf.createConnection();
141 		con1.start();
142 		con1.close();  // should be ignored
143 		Connection con2 = scf.createConnection();
144 		con2.start();
145 		con2.close();  // should be ignored
146 		scf.destroy();  // should trigger actual close
147 
148 		cfControl.verify();
149 		conControl.verify();
150 	}
151 
testWithQueueConnectionFactoryAndJms11Usage()152 	public void testWithQueueConnectionFactoryAndJms11Usage() throws JMSException {
153 		MockControl cfControl = MockControl.createControl(QueueConnectionFactory.class);
154 		QueueConnectionFactory cf = (QueueConnectionFactory) cfControl.getMock();
155 		MockControl conControl = MockControl.createControl(QueueConnection.class);
156 		QueueConnection con = (QueueConnection) conControl.getMock();
157 
158 		cf.createConnection();
159 		cfControl.setReturnValue(con, 1);
160 		con.start();
161 		conControl.setVoidCallable(1);
162 		con.stop();
163 		conControl.setVoidCallable(1);
164 		con.close();
165 		conControl.setVoidCallable(1);
166 
167 		cfControl.replay();
168 		conControl.replay();
169 
170 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
171 		Connection con1 = scf.createConnection();
172 		con1.start();
173 		con1.close();  // should be ignored
174 		Connection con2 = scf.createConnection();
175 		con2.start();
176 		con2.close();  // should be ignored
177 		scf.destroy();  // should trigger actual close
178 
179 		cfControl.verify();
180 		conControl.verify();
181 	}
182 
testWithQueueConnectionFactoryAndJms102Usage()183 	public void testWithQueueConnectionFactoryAndJms102Usage() throws JMSException {
184 		MockControl cfControl = MockControl.createControl(QueueConnectionFactory.class);
185 		QueueConnectionFactory cf = (QueueConnectionFactory) cfControl.getMock();
186 		MockControl conControl = MockControl.createControl(QueueConnection.class);
187 		QueueConnection con = (QueueConnection) conControl.getMock();
188 
189 		cf.createQueueConnection();
190 		cfControl.setReturnValue(con, 1);
191 		con.start();
192 		conControl.setVoidCallable(1);
193 		con.stop();
194 		conControl.setVoidCallable(1);
195 		con.close();
196 		conControl.setVoidCallable(1);
197 
198 		cfControl.replay();
199 		conControl.replay();
200 
201 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
202 		Connection con1 = scf.createQueueConnection();
203 		con1.start();
204 		con1.close();  // should be ignored
205 		Connection con2 = scf.createQueueConnection();
206 		con2.start();
207 		con2.close();  // should be ignored
208 		scf.destroy();  // should trigger actual close
209 
210 		cfControl.verify();
211 		conControl.verify();
212 	}
213 
testWithTopicConnectionFactoryAndJms11Usage()214 	public void testWithTopicConnectionFactoryAndJms11Usage() throws JMSException {
215 		MockControl cfControl = MockControl.createControl(TopicConnectionFactory.class);
216 		TopicConnectionFactory cf = (TopicConnectionFactory) cfControl.getMock();
217 		MockControl conControl = MockControl.createControl(TopicConnection.class);
218 		TopicConnection con = (TopicConnection) conControl.getMock();
219 
220 		cf.createConnection();
221 		cfControl.setReturnValue(con, 1);
222 		con.start();
223 		conControl.setVoidCallable(1);
224 		con.stop();
225 		conControl.setVoidCallable(1);
226 		con.close();
227 		conControl.setVoidCallable(1);
228 
229 		cfControl.replay();
230 		conControl.replay();
231 
232 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
233 		Connection con1 = scf.createConnection();
234 		con1.start();
235 		con1.close();  // should be ignored
236 		Connection con2 = scf.createConnection();
237 		con2.start();
238 		con2.close();  // should be ignored
239 		scf.destroy();  // should trigger actual close
240 
241 		cfControl.verify();
242 		conControl.verify();
243 	}
244 
testWithTopicConnectionFactoryAndJms102Usage()245 	public void testWithTopicConnectionFactoryAndJms102Usage() throws JMSException {
246 		MockControl cfControl = MockControl.createControl(TopicConnectionFactory.class);
247 		TopicConnectionFactory cf = (TopicConnectionFactory) cfControl.getMock();
248 		MockControl conControl = MockControl.createControl(TopicConnection.class);
249 		TopicConnection con = (TopicConnection) conControl.getMock();
250 
251 		cf.createTopicConnection();
252 		cfControl.setReturnValue(con, 1);
253 		con.start();
254 		conControl.setVoidCallable(1);
255 		con.stop();
256 		conControl.setVoidCallable(1);
257 		con.close();
258 		conControl.setVoidCallable(1);
259 
260 		cfControl.replay();
261 		conControl.replay();
262 
263 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
264 		Connection con1 = scf.createTopicConnection();
265 		con1.start();
266 		con1.close();  // should be ignored
267 		Connection con2 = scf.createTopicConnection();
268 		con2.start();
269 		con2.close();  // should be ignored
270 		scf.destroy();  // should trigger actual close
271 
272 		cfControl.verify();
273 		conControl.verify();
274 	}
275 
testWithConnectionFactoryAndClientId()276 	public void testWithConnectionFactoryAndClientId() throws JMSException {
277 		MockControl cfControl = MockControl.createControl(ConnectionFactory.class);
278 		ConnectionFactory cf = (ConnectionFactory) cfControl.getMock();
279 		MockControl conControl = MockControl.createControl(Connection.class);
280 		Connection con = (Connection) conControl.getMock();
281 
282 		cf.createConnection();
283 		cfControl.setReturnValue(con, 1);
284 		con.setClientID("myId");
285 		conControl.setVoidCallable(1);
286 		con.start();
287 		conControl.setVoidCallable(1);
288 		con.stop();
289 		conControl.setVoidCallable(1);
290 		con.close();
291 		conControl.setVoidCallable(1);
292 
293 		cfControl.replay();
294 		conControl.replay();
295 
296 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
297 		scf.setClientId("myId");
298 		Connection con1 = scf.createConnection();
299 		con1.start();
300 		con1.close();  // should be ignored
301 		Connection con2 = scf.createConnection();
302 		con2.start();
303 		con2.close();  // should be ignored
304 		scf.destroy();  // should trigger actual close
305 
306 		cfControl.verify();
307 		conControl.verify();
308 	}
309 
testWithConnectionFactoryAndExceptionListener()310 	public void testWithConnectionFactoryAndExceptionListener() throws JMSException {
311 		MockControl cfControl = MockControl.createControl(ConnectionFactory.class);
312 		ConnectionFactory cf = (ConnectionFactory) cfControl.getMock();
313 		MockControl conControl = MockControl.createControl(Connection.class);
314 		Connection con = (Connection) conControl.getMock();
315 
316 		ExceptionListener listener = new ChainedExceptionListener();
317 		cf.createConnection();
318 		cfControl.setReturnValue(con, 1);
319 		con.setExceptionListener(listener);
320 		conControl.setVoidCallable(1);
321 		con.getExceptionListener();
322 		conControl.setReturnValue(listener, 1);
323 		con.start();
324 		conControl.setVoidCallable(1);
325 		con.stop();
326 		conControl.setVoidCallable(1);
327 		con.close();
328 		conControl.setVoidCallable(1);
329 
330 		cfControl.replay();
331 		conControl.replay();
332 
333 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
334 		scf.setExceptionListener(listener);
335 		Connection con1 = scf.createConnection();
336 		assertEquals(listener, con1.getExceptionListener());
337 		con1.start();
338 		con1.stop();  // should be ignored
339 		con1.close();  // should be ignored
340 		Connection con2 = scf.createConnection();
341 		con2.start();
342 		con2.stop();  // should be ignored
343 		con2.close();  // should be ignored
344 		scf.destroy();  // should trigger actual close
345 
346 		cfControl.verify();
347 		conControl.verify();
348 	}
349 
testWithConnectionFactoryAndReconnectOnException()350 	public void testWithConnectionFactoryAndReconnectOnException() throws JMSException {
351 		MockControl cfControl = MockControl.createControl(ConnectionFactory.class);
352 		ConnectionFactory cf = (ConnectionFactory) cfControl.getMock();
353 		TestConnection con = new TestConnection();
354 
355 		cf.createConnection();
356 		cfControl.setReturnValue(con, 2);
357 		cfControl.replay();
358 
359 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
360 		scf.setReconnectOnException(true);
361 		Connection con1 = scf.createConnection();
362 		assertNull(con1.getExceptionListener());
363 		con1.start();
364 		con.getExceptionListener().onException(new JMSException(""));
365 		Connection con2 = scf.createConnection();
366 		con2.start();
367 		scf.destroy();  // should trigger actual close
368 
369 		cfControl.verify();
370 		assertEquals(2, con.getStartCount());
371 		assertEquals(2, con.getCloseCount());
372 	}
373 
testWithConnectionFactoryAndExceptionListenerAndReconnectOnException()374 	public void testWithConnectionFactoryAndExceptionListenerAndReconnectOnException() throws JMSException {
375 		MockControl cfControl = MockControl.createControl(ConnectionFactory.class);
376 		ConnectionFactory cf = (ConnectionFactory) cfControl.getMock();
377 		TestConnection con = new TestConnection();
378 
379 		TestExceptionListener listener = new TestExceptionListener();
380 		cf.createConnection();
381 		cfControl.setReturnValue(con, 2);
382 		cfControl.replay();
383 
384 		SingleConnectionFactory scf = new SingleConnectionFactory(cf);
385 		scf.setExceptionListener(listener);
386 		scf.setReconnectOnException(true);
387 		Connection con1 = scf.createConnection();
388 		assertSame(listener, con1.getExceptionListener());
389 		con1.start();
390 		con.getExceptionListener().onException(new JMSException(""));
391 		Connection con2 = scf.createConnection();
392 		con2.start();
393 		scf.destroy();  // should trigger actual close
394 
395 		cfControl.verify();
396 		assertEquals(2, con.getStartCount());
397 		assertEquals(2, con.getCloseCount());
398 		assertEquals(1, listener.getCount());
399 	}
400 
testConnectionFactory102WithQueue()401 	public void testConnectionFactory102WithQueue() throws JMSException {
402 		MockControl cfControl = MockControl.createControl(QueueConnectionFactory.class);
403 		QueueConnectionFactory cf = (QueueConnectionFactory) cfControl.getMock();
404 		MockControl conControl = MockControl.createControl(QueueConnection.class);
405 		QueueConnection con = (QueueConnection) conControl.getMock();
406 
407 		cf.createQueueConnection();
408 		cfControl.setReturnValue(con, 1);
409 		con.start();
410 		conControl.setVoidCallable(1);
411 		con.stop();
412 		conControl.setVoidCallable(1);
413 		con.close();
414 		conControl.setVoidCallable(1);
415 
416 		cfControl.replay();
417 		conControl.replay();
418 
419 		SingleConnectionFactory scf = new SingleConnectionFactory102(cf, false);
420 		QueueConnection con1 = scf.createQueueConnection();
421 		con1.start();
422 		con1.close();  // should be ignored
423 		QueueConnection con2 = scf.createQueueConnection();
424 		con2.start();
425 		con2.close();  // should be ignored
426 		scf.destroy();  // should trigger actual close
427 
428 		cfControl.verify();
429 		conControl.verify();
430 	}
431 
testConnectionFactory102WithTopic()432 	public void testConnectionFactory102WithTopic() throws JMSException {
433 		MockControl cfControl = MockControl.createControl(TopicConnectionFactory.class);
434 		TopicConnectionFactory cf = (TopicConnectionFactory) cfControl.getMock();
435 		MockControl conControl = MockControl.createControl(TopicConnection.class);
436 		TopicConnection con = (TopicConnection) conControl.getMock();
437 
438 		cf.createTopicConnection();
439 		cfControl.setReturnValue(con, 1);
440 		con.start();
441 		conControl.setVoidCallable(1);
442 		con.stop();
443 		conControl.setVoidCallable(1);
444 		con.close();
445 		conControl.setVoidCallable(1);
446 
447 		cfControl.replay();
448 		conControl.replay();
449 
450 		SingleConnectionFactory scf = new SingleConnectionFactory102(cf, true);
451 		TopicConnection con1 = scf.createTopicConnection();
452 		con1.start();
453 		con1.close();  // should be ignored
454 		TopicConnection con2 = scf.createTopicConnection();
455 		con2.start();
456 		con2.close();  // should be ignored
457 		scf.destroy();  // should trigger actual close
458 
459 		cfControl.verify();
460 		conControl.verify();
461 	}
462 
testCachingConnectionFactory()463 	public void testCachingConnectionFactory() throws JMSException {
464 		MockControl cfControl = MockControl.createControl(ConnectionFactory.class);
465 		ConnectionFactory cf = (ConnectionFactory) cfControl.getMock();
466 		MockControl conControl = MockControl.createControl(Connection.class);
467 		Connection con = (Connection) conControl.getMock();
468 		MockControl txSessionControl = MockControl.createControl(Session.class);
469 		Session txSession = (Session) txSessionControl.getMock();
470 		MockControl nonTxSessionControl = MockControl.createControl(Session.class);
471 		Session nonTxSession = (Session) nonTxSessionControl.getMock();
472 
473 		cf.createConnection();
474 		cfControl.setReturnValue(con, 1);
475 		con.createSession(true, Session.AUTO_ACKNOWLEDGE);
476 		conControl.setReturnValue(txSession, 1);
477 		txSession.getTransacted();
478 		txSessionControl.setReturnValue(true, 1);
479 		txSession.commit();
480 		txSessionControl.setVoidCallable(1);
481 		txSession.close();
482 		txSessionControl.setVoidCallable(1);
483 		con.createSession(false, Session.CLIENT_ACKNOWLEDGE);
484 		conControl.setReturnValue(nonTxSession, 1);
485 		nonTxSession.close();
486 		nonTxSessionControl.setVoidCallable(1);
487 		con.start();
488 		conControl.setVoidCallable(1);
489 		con.stop();
490 		conControl.setVoidCallable(1);
491 		con.close();
492 		conControl.setVoidCallable(1);
493 
494 		cfControl.replay();
495 		conControl.replay();
496 		txSessionControl.replay();
497 		nonTxSessionControl.replay();
498 
499 		CachingConnectionFactory scf = new CachingConnectionFactory(cf);
500 		scf.setReconnectOnException(false);
501 		Connection con1 = scf.createConnection();
502 		Session session1 = con1.createSession(true, Session.AUTO_ACKNOWLEDGE);
503 		session1.getTransacted();
504 		session1.close();  // should lead to rollback
505 		session1 = con1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
506 		session1.close();  // should be ignored
507 		con1.start();
508 		con1.close();  // should be ignored
509 		Connection con2 = scf.createConnection();
510 		Session session2 = con2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
511 		session2.close();  // should be ignored
512 		session2 = con2.createSession(true, Session.AUTO_ACKNOWLEDGE);
513 		session2.commit();
514 		session2.close();  // should be ignored
515 		con2.start();
516 		con2.close();  // should be ignored
517 		scf.destroy();  // should trigger actual close
518 
519 		cfControl.verify();
520 		conControl.verify();
521 		txSessionControl.verify();
522 		nonTxSessionControl.verify();
523 	}
524 
testCachingConnectionFactoryWithQueueConnectionFactoryAndJms102Usage()525 	public void testCachingConnectionFactoryWithQueueConnectionFactoryAndJms102Usage() throws JMSException {
526 		MockControl cfControl = MockControl.createControl(QueueConnectionFactory.class);
527 		QueueConnectionFactory cf = (QueueConnectionFactory) cfControl.getMock();
528 		MockControl conControl = MockControl.createControl(QueueConnection.class);
529 		QueueConnection con = (QueueConnection) conControl.getMock();
530 		MockControl txSessionControl = MockControl.createControl(QueueSession.class);
531 		QueueSession txSession = (QueueSession) txSessionControl.getMock();
532 		MockControl nonTxSessionControl = MockControl.createControl(QueueSession.class);
533 		QueueSession nonTxSession = (QueueSession) nonTxSessionControl.getMock();
534 
535 		cf.createQueueConnection();
536 		cfControl.setReturnValue(con, 1);
537 		con.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
538 		conControl.setReturnValue(txSession, 1);
539 		txSession.getTransacted();
540 		txSessionControl.setReturnValue(true, 1);
541 		txSession.rollback();
542 		txSessionControl.setVoidCallable(1);
543 		txSession.close();
544 		txSessionControl.setVoidCallable(1);
545 		con.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
546 		conControl.setReturnValue(nonTxSession, 1);
547 		nonTxSession.close();
548 		nonTxSessionControl.setVoidCallable(1);
549 		con.start();
550 		conControl.setVoidCallable(1);
551 		con.stop();
552 		conControl.setVoidCallable(1);
553 		con.close();
554 		conControl.setVoidCallable(1);
555 
556 		cfControl.replay();
557 		conControl.replay();
558 		txSessionControl.replay();
559 		nonTxSessionControl.replay();
560 
561 		CachingConnectionFactory scf = new CachingConnectionFactory(cf);
562 		scf.setReconnectOnException(false);
563 		Connection con1 = scf.createQueueConnection();
564 		Session session1 = con1.createSession(true, Session.AUTO_ACKNOWLEDGE);
565 		session1.rollback();
566 		session1.close();  // should be ignored
567 		session1 = con1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
568 		session1.close();  // should be ignored
569 		con1.start();
570 		con1.close();  // should be ignored
571 		QueueConnection con2 = scf.createQueueConnection();
572 		Session session2 = con2.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
573 		session2.close();  // should be ignored
574 		session2 = con2.createSession(true, Session.AUTO_ACKNOWLEDGE);
575 		session2.getTransacted();
576 		session2.close();  // should lead to rollback
577 		con2.start();
578 		con2.close();  // should be ignored
579 		scf.destroy();  // should trigger actual close
580 
581 		cfControl.verify();
582 		conControl.verify();
583 		txSessionControl.verify();
584 		nonTxSessionControl.verify();
585 	}
586 
testCachingConnectionFactoryWithTopicConnectionFactoryAndJms102Usage()587 	public void testCachingConnectionFactoryWithTopicConnectionFactoryAndJms102Usage() throws JMSException {
588 		MockControl cfControl = MockControl.createControl(TopicConnectionFactory.class);
589 		TopicConnectionFactory cf = (TopicConnectionFactory) cfControl.getMock();
590 		MockControl conControl = MockControl.createControl(TopicConnection.class);
591 		TopicConnection con = (TopicConnection) conControl.getMock();
592 		MockControl txSessionControl = MockControl.createControl(TopicSession.class);
593 		TopicSession txSession = (TopicSession) txSessionControl.getMock();
594 		MockControl nonTxSessionControl = MockControl.createControl(TopicSession.class);
595 		TopicSession nonTxSession = (TopicSession) nonTxSessionControl.getMock();
596 
597 		cf.createTopicConnection();
598 		cfControl.setReturnValue(con, 1);
599 		con.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
600 		conControl.setReturnValue(txSession, 1);
601 		txSession.getTransacted();
602 		txSessionControl.setReturnValue(true, 2);
603 		txSession.close();
604 		txSessionControl.setVoidCallable(1);
605 		con.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);
606 		conControl.setReturnValue(nonTxSession, 1);
607 		nonTxSession.close();
608 		nonTxSessionControl.setVoidCallable(1);
609 		con.start();
610 		conControl.setVoidCallable(1);
611 		con.stop();
612 		conControl.setVoidCallable(1);
613 		con.close();
614 		conControl.setVoidCallable(1);
615 
616 		cfControl.replay();
617 		conControl.replay();
618 		txSessionControl.replay();
619 		nonTxSessionControl.replay();
620 
621 		CachingConnectionFactory scf = new CachingConnectionFactory(cf);
622 		scf.setReconnectOnException(false);
623 		Connection con1 = scf.createTopicConnection();
624 		Session session1 = con1.createSession(true, Session.AUTO_ACKNOWLEDGE);
625 		session1.getTransacted();
626 		session1.close();  // should lead to rollback
627 		session1 = con1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
628 		session1.close();  // should be ignored
629 		con1.start();
630 		con1.close();  // should be ignored
631 		TopicConnection con2 = scf.createTopicConnection();
632 		Session session2 = con2.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);
633 		session2.close();  // should be ignored
634 		session2 = con2.createSession(true, Session.AUTO_ACKNOWLEDGE);
635 		session2.getTransacted();
636 		session2.close();  // should be ignored
637 		con2.start();
638 		con2.close();  // should be ignored
639 		scf.destroy();  // should trigger actual close
640 
641 		cfControl.verify();
642 		conControl.verify();
643 		txSessionControl.verify();
644 		nonTxSessionControl.verify();
645 	}
646 
647 }
648