diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java index 6d1b4096f9..54178c014d 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQDestination.java @@ -386,14 +386,19 @@ public class ActiveMQDestination extends JNDIStorable implements Destination, Se public void delete() throws JMSException { if (session != null) { - if (session.getCoreSession().isClosed()) { - // Temporary queues will be deleted when the connection is closed.. nothing to be done then! - return; - } - if (isQueue()) { - session.deleteTemporaryQueue(this); - } else { - session.deleteTemporaryTopic(this); + /** + * The status of the session used to create the temporary destination is uncertain, but the JMS spec states + * that the lifetime of the temporary destination is tied to the connection so even if the originating + * session is closed the temporary destination should still be deleted. Therefore, just create a new one + * and close it after the temporary destination is deleted. This is necessary because the Core API is + * predicated on having a Core ClientSession which is encapsulated by the JMS session implementation. + */ + try (ActiveMQSession sessionToUse = (ActiveMQSession) session.getConnection().createSession()) { + if (isQueue()) { + sessionToUse.deleteTemporaryQueue(this); + } else { + sessionToUse.deleteTemporaryTopic(this); + } } } } diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java index 5b75f7f472..ae6828365e 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java @@ -1190,6 +1190,10 @@ public class ActiveMQSession implements QueueSession, TopicSession { } } + public ActiveMQConnection getConnection() { + return connection; + } + // Protected ----------------------------------------------------- diff --git a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/TemporaryDestinationTest.java b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/TemporaryDestinationTest.java index 87912781ef..2a4ad4194f 100644 --- a/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/TemporaryDestinationTest.java +++ b/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/TemporaryDestinationTest.java @@ -27,6 +27,7 @@ import javax.jms.TemporaryTopic; import javax.jms.TextMessage; import javax.naming.NamingException; +import org.apache.activemq.artemis.core.settings.impl.AddressSettings; import org.apache.activemq.artemis.jms.tests.util.ProxyAssertSupport; import org.junit.Test; @@ -265,6 +266,126 @@ public class TemporaryDestinationTest extends JMSTestCase { } } + @Test + public void testTemporaryQueueDeletedAfterSessionClosed() throws Exception { + servers.get(0).getActiveMQServer().getAddressSettingsRepository().addMatch("#", new AddressSettings().setAutoCreateAddresses(false).setAutoCreateQueues(false)); + + Connection conn = null; + + try { + conn = createConnection(); + + Session producerSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Session consumerSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Make sure temporary queue cannot be used after it has been deleted + + TemporaryQueue tempQueue = producerSession.createTemporaryQueue(); + + MessageProducer producer = producerSession.createProducer(tempQueue); + + MessageConsumer consumer = consumerSession.createConsumer(tempQueue); + + conn.start(); + + final String messageText = "This is a message"; + + Message m = producerSession.createTextMessage(messageText); + + producer.send(m); + + TextMessage m2 = (TextMessage) consumer.receive(2000); + + ProxyAssertSupport.assertNotNull(m2); + + ProxyAssertSupport.assertEquals(messageText, m2.getText()); + + consumer.close(); + + consumerSession.close(); + + producer.close(); + + producerSession.close(); + + tempQueue.delete(); + + producerSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + + try { + producer = producerSession.createProducer(tempQueue); + producer.send(m); + ProxyAssertSupport.fail(); + } catch (JMSException e) { + } + } finally { + if (conn != null) { + conn.close(); + } + } + } + + @Test + public void testTemporaryTopicDeletedAfterSessionClosed() throws Exception { + servers.get(0).getActiveMQServer().getAddressSettingsRepository().addMatch("#", new AddressSettings().setAutoCreateAddresses(false).setAutoCreateQueues(false)); + + Connection conn = null; + + try { + conn = createConnection(); + + Session producerSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + + Session consumerSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Make sure temporary topic cannot be used after it has been deleted + + TemporaryTopic tempTopic = producerSession.createTemporaryTopic(); + + MessageProducer producer = producerSession.createProducer(tempTopic); + + MessageConsumer consumer = consumerSession.createConsumer(tempTopic); + + conn.start(); + + final String messageText = "This is a message"; + + Message m = producerSession.createTextMessage(messageText); + + producer.send(m); + + TextMessage m2 = (TextMessage) consumer.receive(2000); + + ProxyAssertSupport.assertNotNull(m2); + + ProxyAssertSupport.assertEquals(messageText, m2.getText()); + + consumer.close(); + + consumerSession.close(); + + producer.close(); + + producerSession.close(); + + tempTopic.delete(); + + producerSession = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); + + try { + producer = producerSession.createProducer(tempTopic); + producer.send(m); + ProxyAssertSupport.fail(); + } catch (JMSException e) { + } + } finally { + if (conn != null) { + conn.close(); + } + } + } + @Test public void testTemporaryTopicBasic() throws Exception { Connection conn = null;