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());
+ }
}
}
}