Author: rmannibucau Date: Fri Aug 9 07:18:25 2013 New Revision: 1512187 URL: http://svn.apache.org/r1512187 Log: TOMEE-1013 starting request/session/conversation scopes in tomee embedded arquillian adapter + avoiding some potential mem leaks for stateful cache
Modified: tomee/tomee/trunk/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimpleCache.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java Modified: tomee/tomee/trunk/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java?rev=1512187&r1=1512186&r2=1512187&view=diff ============================================================================== --- tomee/tomee/trunk/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java (original) +++ tomee/tomee/trunk/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java Fri Aug 9 07:18:25 2013 @@ -24,6 +24,8 @@ import org.apache.openejb.config.Additio import org.apache.openejb.loader.SystemInstance; import org.apache.tomee.embedded.Configuration; import org.apache.tomee.embedded.Container; +import org.apache.webbeans.config.WebBeansContext; +import org.apache.webbeans.web.lifecycle.test.MockHttpSession; import org.jboss.arquillian.container.spi.client.container.DeploymentException; import org.jboss.arquillian.container.spi.client.container.LifecycleException; import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription; @@ -33,6 +35,10 @@ import org.jboss.arquillian.container.sp import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.exporter.ZipExporter; +import javax.enterprise.context.ConversationScoped; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.context.SessionScoped; +import javax.servlet.http.HttpSession; import java.io.File; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -41,6 +47,8 @@ public class EmbeddedTomEEContainer exte private static final Map<Archive<?>, File> ARCHIVES = new ConcurrentHashMap<Archive<?>, File>(); + private static final Map<String, MockHttpSession> SESSIONS = new ConcurrentHashMap<String, MockHttpSession>(); + private Container container; @Override @@ -128,6 +136,8 @@ public class EmbeddedTomEEContainer exte httpContext.add(new Servlet("ArquillianServletRunner", "/" + context)); this.addServlets(httpContext, info); + startCdiContexts(name); // ensure tests can use request/session scopes even if we don't have a request + return new ProtocolMetaData().addContext(httpContext); } catch (Exception e) { e.printStackTrace(); @@ -137,10 +147,11 @@ public class EmbeddedTomEEContainer exte @Override public void undeploy(final Archive<?> archive) throws DeploymentException { - try { - final String name = archive.getName(); + final String name = archive.getName(); + stopCdiContexts(name); + try { this.container.undeploy(name); - } catch (Exception e) { + } catch (final Exception e) { e.printStackTrace(); throw new DeploymentException("Unable to undeploy", e); } @@ -151,4 +162,32 @@ public class EmbeddedTomEEContainer exte } Files.delete(file); } + + private void startCdiContexts(final String name) { + final WebBeansContext wbc = this.container.getAppContexts(name).getWebBeansContext(); + if (wbc.getBeanManagerImpl().isInUse()) { + final MockHttpSession session = new MockHttpSession(); + wbc.getContextsService().startContext(RequestScoped.class, null); + wbc.getContextsService().startContext(SessionScoped.class, session); + wbc.getContextsService().startContext(ConversationScoped.class, null); + + SESSIONS.put(name, session); + } + } + + private void stopCdiContexts(final String name) { + try { + final HttpSession session = SESSIONS.remove(name); + if (session != null) { + final WebBeansContext wbc = container.getAppContexts(container.getInfo(name).appId).getWebBeansContext(); + if (wbc.getBeanManagerImpl().isInUse()) { + wbc.getContextsService().startContext(RequestScoped.class, null); + wbc.getContextsService().startContext(SessionScoped.class, session); + wbc.getContextsService().startContext(ConversationScoped.class, null); + } + } + } catch (final Exception e) { + // no-op + } + } } Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimpleCache.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimpleCache.java?rev=1512187&r1=1512186&r2=1512187&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimpleCache.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimpleCache.java Fri Aug 9 07:18:25 2013 @@ -101,12 +101,19 @@ public class SimpleCache<K, V> implement public synchronized void init() { if (frequency > 0 && future == null) { initScheduledExecutorService(); - - future = executor.scheduleWithFixedDelay(new Runnable() { + + // start any thread in container loader to avoid leaks + final ClassLoader loader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(SimpleCache.class.getClassLoader()); + try { + future = executor.scheduleWithFixedDelay(new Runnable() { public void run() { processLRU(); } }, frequency, frequency, TimeUnit.MILLISECONDS); + } finally { + Thread.currentThread().setContextClassLoader(loader); + } } } Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java?rev=1512187&r1=1512186&r2=1512187&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java Fri Aug 9 07:18:25 2013 @@ -130,8 +130,14 @@ public class StatefulContainerFactory { serviceRecipe.setAllProperties(properties); // invoke recipe + /* the cache should be created with container loader to avoid memory leaks ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader == null) getClass().getClassLoader(); + */ + ClassLoader classLoader = StatefulContainerFactory.class.getClassLoader(); + if (!((String) cache).startsWith("org.apache.openejb")) { // user impl? + classLoader = Thread.currentThread().getContextClassLoader(); + } cache = serviceRecipe.create(classLoader); // assign value Modified: tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java?rev=1512187&r1=1512186&r2=1512187&view=diff ============================================================================== --- tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java (original) +++ tomee/tomee/trunk/tomee/tomee-embedded/src/main/java/org/apache/tomee/embedded/Container.java Fri Aug 9 07:18:25 2013 @@ -249,6 +249,9 @@ public class Container { if (configuration.getProperties() != null) { properties.putAll(configuration.getProperties()); } + if (properties.getProperty("openejb.system.apps") == null) { // will make startup faster and it is rarely useful for embedded case + properties.setProperty("openejb.system.apps", "false"); + } try { final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();