This is an automated email from the ASF dual-hosted git repository. jgallimore pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomee.git
commit cedcf5714344969ba86149cc8501c240e2232f05 Author: Jonathan Gallimore <j...@jrg.me.uk> AuthorDate: Thu Apr 2 16:59:42 2020 +0100 TOMEE-2770 Add a unit test to use JMX to ensure producers are not leaked. --- .../resource/activemq/jms2/JMSContextImpl.java | 3 ++ .../org/apache/openejb/activemq/JMS2AMQTest.java | 43 +++++++++++++++++++++- .../java/org/superbiz/jms/CustomJmsService.java | 3 ++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/JMSContextImpl.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/JMSContextImpl.java index 573624d..872b1c9 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/JMSContextImpl.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/JMSContextImpl.java @@ -143,6 +143,9 @@ public class JMSContextImpl implements JMSContext { public void close() { try { synchronized (this) { + if (session != null) { + session.close(); + } if (connection != null) { connection.close(); } diff --git a/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMS2AMQTest.java b/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMS2AMQTest.java index ba6ab54..acffaaf 100644 --- a/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMS2AMQTest.java +++ b/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMS2AMQTest.java @@ -27,15 +27,19 @@ import org.apache.openejb.testing.SimpleLog; import org.apache.openejb.testng.PropertiesBuilder; import org.apache.webbeans.config.WebBeansContext; import org.apache.webbeans.spi.ContextsService; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import javax.annotation.Resource; import javax.ejb.ActivationConfigProperty; +import javax.ejb.EJB; import javax.ejb.MessageDriven; +import javax.ejb.Singleton; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; import javax.enterprise.context.RequestScoped; -import javax.enterprise.context.SessionScoped; import javax.inject.Inject; import javax.jms.ConnectionFactory; import javax.jms.JMSConnectionFactory; @@ -48,6 +52,8 @@ import javax.jms.MessageListener; import javax.jms.Queue; import javax.jms.TextMessage; import javax.jms.XAConnectionFactory; +import javax.management.MBeanServer; +import javax.management.ObjectName; import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; import javax.transaction.NotSupportedException; @@ -56,7 +62,9 @@ import javax.transaction.SystemException; import javax.transaction.TransactionScoped; import javax.transaction.UserTransaction; import java.io.Serializable; +import java.lang.management.ManagementFactory; import java.util.Properties; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -96,7 +104,7 @@ public class JMS2AMQTest { } @Module - @Classes(cdi = true, value = JustHereToCheckDeploymentIsOk.class) + @Classes(cdi = true, value = { JustHereToCheckDeploymentIsOk.class, ProducerBean.class }) public MessageDrivenBean jar() { return new MessageDrivenBean(Listener.class); } @@ -129,6 +137,9 @@ public class JMS2AMQTest { @Resource private UserTransaction ut; + @EJB + private ProducerBean pb; + @Before public void resetLatch() { Listener.reset(); @@ -286,6 +297,19 @@ public class JMS2AMQTest { } @Test + public void sendToMdbWithTxAndCheckLeaks() throws Exception { + for (int i = 0; i < 50; i++) { + pb.sendInNewTx(); + } + + assertTrue(Listener.sync()); + + final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); + Set<ObjectName> objs = mBeanServer.queryNames(new ObjectName("org.apache.activemq:type=Broker,brokerName=localhost,endpoint=dynamicProducer,*"), null); + Assert.assertEquals(0, objs.size()); + } + + @Test public void receive() throws InterruptedException { final String text = TEXT + "2"; final AtomicReference<Throwable> error = new AtomicReference<>(); @@ -422,4 +446,19 @@ public class JMS2AMQTest { assertNotNull(context); } } + + @Singleton + public static class ProducerBean { + @Inject + @JMSConnectionFactory("cf") + private JMSContext context; + + @Resource(name = "target") + private Queue destination; + + @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) + public void sendInNewTx() { + context.createProducer().send(destination, TEXT); + } + } } diff --git a/examples/simple-jms-context/src/main/java/org/superbiz/jms/CustomJmsService.java b/examples/simple-jms-context/src/main/java/org/superbiz/jms/CustomJmsService.java index f14fc18..38af21d 100644 --- a/examples/simple-jms-context/src/main/java/org/superbiz/jms/CustomJmsService.java +++ b/examples/simple-jms-context/src/main/java/org/superbiz/jms/CustomJmsService.java @@ -18,6 +18,8 @@ package org.superbiz.jms; import javax.annotation.Resource; import javax.ejb.Stateless; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; import javax.inject.Inject; import javax.jms.*; import javax.ws.rs.GET; @@ -26,6 +28,7 @@ import javax.ws.rs.Path; @Stateless @Path("message") +@TransactionAttribute(TransactionAttributeType.NEVER) public class CustomJmsService { @Resource