You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2017/06/27 10:40:20 UTC

tomee git commit: TOMEE-2077 trying to support multiple deployment classloader for embedded deployments

Repository: tomee
Updated Branches:
  refs/heads/master 9104b7c30 -> 1528ad30e


TOMEE-2077 trying to support multiple deployment classloader for embedded deployments


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/1528ad30
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/1528ad30
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/1528ad30

Branch: refs/heads/master
Commit: 1528ad30ea38bdca0440c3a3ad5ab88280a7d00d
Parents: 9104b7c
Author: rmannibucau <rm...@apache.org>
Authored: Tue Jun 27 12:40:13 2017 +0200
Committer: rmannibucau <rm...@apache.org>
Committed: Tue Jun 27 12:40:13 2017 +0200

----------------------------------------------------------------------
 .../openejb/arquillian/common/TestObserver.java | 29 +++++++++---
 .../openejb/OpenEJBDeployableContainer.java     | 24 ++++++----
 .../embedded/EmbeddedTomEEContainer.java        | 47 +++++++++++++-------
 3 files changed, 71 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/1528ad30/arquillian/arquillian-common/src/main/java/org/apache/openejb/arquillian/common/TestObserver.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-common/src/main/java/org/apache/openejb/arquillian/common/TestObserver.java b/arquillian/arquillian-common/src/main/java/org/apache/openejb/arquillian/common/TestObserver.java
index 5bf447b..cc53997 100644
--- a/arquillian/arquillian-common/src/main/java/org/apache/openejb/arquillian/common/TestObserver.java
+++ b/arquillian/arquillian-common/src/main/java/org/apache/openejb/arquillian/common/TestObserver.java
@@ -33,10 +33,12 @@ import org.jboss.arquillian.test.spi.TestClass;
 import org.jboss.arquillian.test.spi.event.suite.TestEvent;
 
 import javax.enterprise.context.spi.CreationalContext;
+import java.util.HashMap;
+import java.util.Map;
 
 public class TestObserver {
     @Inject
-    private Instance<ClassLoader> classLoader;
+    private Instance<ClassLoaders> classLoader;
 
     @Inject
     private Instance<TestClass> testClass;
@@ -50,9 +52,9 @@ public class TestObserver {
 
     public void observesDeploy(@Observes final AfterDeploy afterDeployment) {
         contextProducer.set(new DeploymentContext(Thread.currentThread().getContextClassLoader()));
-        final ClassLoader loader = classLoader.get();
-        if (loader != null) {
-            setTCCL(loader);
+        final ClassLoaders loader = classLoader.get();
+        if (loader != null && loader.classloaders.containsKey(afterDeployment.getDeployment().getName())) {
+            setTCCL(loader.classloaders.get(afterDeployment.getDeployment().getName()));
         }
     }
 
@@ -79,8 +81,11 @@ public class TestObserver {
             oldCtx = ThreadContext.enter(new ThreadContext(context, null));
         } else {
             oldCl = Thread.currentThread().getContextClassLoader();
-            if (classLoader.get() != null) {
-                setTCCL(classLoader.get());
+            final ClassLoaders classLoaders = classLoader.get();
+            if (classLoaders != null) {
+                final ClassLoader loader = classLoaders.classloaders.size() == 1 /*assume it is the one we want*/ ?
+                        classLoaders.classloaders.values().iterator().next() : oldCl /* we don't know the deployment so just passthrough */;
+                setTCCL(loader);
             }
         }
         try {
@@ -141,4 +146,16 @@ public class TestObserver {
             this.loader = loader;
         }
     }
+
+    public static class ClassLoaders { // to support multiple deployments otherwise we can lead a broken classloader
+        private final Map<String, ClassLoader> classloaders = new HashMap<>();
+
+        public void register(final String name, final ClassLoader loader) {
+            classloaders.put(name, loader);
+        }
+
+        public void unregister(final String name) {
+            classloaders.remove(name);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/1528ad30/arquillian/arquillian-openejb-embedded/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-openejb-embedded/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java b/arquillian/arquillian-openejb-embedded/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
index a267c99..34b0dee 100644
--- a/arquillian/arquillian-openejb-embedded/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
+++ b/arquillian/arquillian-openejb-embedded/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBDeployableContainer.java
@@ -23,6 +23,7 @@ import org.apache.openejb.OpenEJB;
 import org.apache.openejb.OpenEJBRuntimeException;
 import org.apache.openejb.OpenEjbContainer;
 import org.apache.openejb.arquillian.common.ArquillianUtil;
+import org.apache.openejb.arquillian.common.TestObserver;
 import org.apache.openejb.arquillian.openejb.server.ServiceManagers;
 import org.apache.openejb.assembler.classic.AppInfo;
 import org.apache.openejb.assembler.classic.Assembler;
@@ -60,6 +61,11 @@ import org.jboss.arquillian.test.spi.annotation.SuiteScoped;
 import org.jboss.shrinkwrap.api.Archive;
 import org.jboss.shrinkwrap.descriptor.api.Descriptor;
 
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
 import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.io.IOException;
@@ -72,11 +78,6 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpSession;
 
 import static org.apache.openejb.cdi.ScopeHelper.startContexts;
 import static org.apache.openejb.cdi.ScopeHelper.stopContexts;
@@ -136,7 +137,7 @@ public class OpenEJBDeployableContainer implements DeployableContainer<OpenEJBCo
 
     @Inject
     @SuiteScoped
-    private InstanceProducer<ClassLoader> classLoader;
+    private InstanceProducer<TestObserver.ClassLoaders> classLoader;
 
     @Inject
     private Instance<Closeables> closeables;
@@ -253,7 +254,14 @@ public class OpenEJBDeployableContainer implements DeployableContainer<OpenEJBCo
             appInfoProducer.set(info.appInfo);
             appContextProducer.set(info.appCtx);
             final ClassLoader loader = info.appCtx.getWebContexts().isEmpty() ? info.appCtx.getClassLoader() : info.appCtx.getWebContexts().iterator().next().getClassLoader();
-            classLoader.set(loader == null ? info.appCtx.getClassLoader() : loader);
+            final ClassLoader classLoader = loader == null ? info.appCtx.getClassLoader() : loader;
+
+            TestObserver.ClassLoaders classLoaders = this.classLoader.get();
+            if (classLoaders == null) {
+                classLoaders = new TestObserver.ClassLoaders();
+                this.classLoader.set(classLoaders);
+            }
+            classLoaders.register(archive.getName(), classLoader);
         } catch (final Exception e) {
             throw new DeploymentException("can't deploy " + archive.getName(), e);
         }
@@ -362,7 +370,7 @@ public class OpenEJBDeployableContainer implements DeployableContainer<OpenEJBCo
 
         // reset classloader for next text
         // otherwise if it was closed something can fail
-        classLoader.set(OpenEJBDeployableContainer.class.getClassLoader());
+        classLoader.get().unregister(archive.getName());
 
         final AppContext ctx = appContext.get();
         if (ctx == null) {

http://git-wip-us.apache.org/repos/asf/tomee/blob/1528ad30/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java
----------------------------------------------------------------------
diff --git a/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java b/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java
index 30daa58..472f22f 100644
--- a/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java
+++ b/arquillian/arquillian-tomee-embedded/src/main/java/org/apache/openejb/arquillian/embedded/EmbeddedTomEEContainer.java
@@ -19,9 +19,11 @@ package org.apache.openejb.arquillian.embedded;
 import org.apache.openejb.arquillian.common.ArquillianFilterRunner;
 import org.apache.openejb.arquillian.common.Files;
 import org.apache.openejb.arquillian.common.TestClassDiscoverer;
+import org.apache.openejb.arquillian.common.TestObserver;
 import org.apache.openejb.arquillian.common.TomEEContainer;
 import org.apache.openejb.assembler.classic.AppInfo;
 import org.apache.openejb.config.AdditionalBeanDiscoverer;
+import org.apache.openejb.core.ParentClassLoaderFinder;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.spi.ContainerSystem;
 import org.apache.tomee.embedded.Configuration;
@@ -57,7 +59,7 @@ public class EmbeddedTomEEContainer extends TomEEContainer<EmbeddedTomEEConfigur
 
     @Inject
     @SuiteScoped
-    private InstanceProducer<ClassLoader> classLoader;
+    private InstanceProducer<TestObserver.ClassLoaders> classLoader;
 
     @Override
     public Class<EmbeddedTomEEConfiguration> getConfigurationClass() {
@@ -164,7 +166,14 @@ public class EmbeddedTomEEContainer extends TomEEContainer<EmbeddedTomEEConfigur
 
             if (dump.isCreated() || !configuration.isSingleDeploymentByArchiveName(name)) {
                 ARCHIVES.put(archive, file);
-                this.container.deploy(name, file);
+                final Thread current = Thread.currentThread();
+                final ClassLoader loader = current.getContextClassLoader();
+                current.setContextClassLoader(ParentClassLoaderFinder.Helper.get()); // multiple deployments, don't leak a loader
+                try {
+                    this.container.deploy(name, file);
+                } finally {
+                    current.setContextClassLoader(loader);
+                }
             }
 
             final AppInfo info = this.container.getInfo(name);
@@ -176,7 +185,12 @@ public class EmbeddedTomEEContainer extends TomEEContainer<EmbeddedTomEEConfigur
 
             startCdiContexts(name); // ensure tests can use request/session scopes even if we don't have a request
 
-            classLoader.set(SystemInstance.get().getComponent(ContainerSystem.class).getAppContext(info.appId).getClassLoader());
+            TestObserver.ClassLoaders classLoaders = this.classLoader.get();
+            if (classLoaders == null) {
+                classLoaders = new TestObserver.ClassLoaders();
+                this.classLoader.set(classLoaders);
+            }
+            classLoaders.register(archive.getName(), SystemInstance.get().getComponent(ContainerSystem.class).getAppContext(info.appId).getClassLoader());
 
             return new ProtocolMetaData().addContext(httpContext);
         } catch (final Exception e) {
@@ -196,18 +210,21 @@ public class EmbeddedTomEEContainer extends TomEEContainer<EmbeddedTomEEConfigur
             this.container.undeploy(name);
         } catch (final Exception e) {
             throw new DeploymentException("Unable to undeploy", e);
-        }
-        final File file = ARCHIVES.remove(archive);
-        if (!configuration.isSingleDumpByArchiveName()) {
-            final File folder = new File(file.getParentFile(), file.getName().substring(0, file.getName().length() - 4));
-            if (folder.exists()) {
-                Files.delete(folder);
-            }
-            Files.delete(file);
-            final File parentFile = file.getParentFile();
-            final File[] parentChildren = parentFile.listFiles();
-            if (parentChildren == null || parentChildren.length == 0) {
-                Files.delete(file.getParentFile());
+        } finally {
+            this.classLoader.get().unregister(archive.getName());
+
+            final File file = ARCHIVES.remove(archive);
+            if (!configuration.isSingleDumpByArchiveName()) {
+                final File folder = new File(file.getParentFile(), file.getName().substring(0, file.getName().length() - 4));
+                if (folder.exists()) {
+                    Files.delete(folder);
+                }
+                Files.delete(file);
+                final File parentFile = file.getParentFile();
+                final File[] parentChildren = parentFile.listFiles();
+                if (parentChildren == null || parentChildren.length == 0) {
+                    Files.delete(file.getParentFile());
+                }
             }
         }
     }