Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.1.x

This commit is contained in:
Jan Bartel 2024-08-04 17:03:52 +10:00
commit 8c276f54d0
10 changed files with 345 additions and 13 deletions

View File

@ -93,9 +93,31 @@ public class ContextFactory implements ObjectFactory
{ {
Context ctx = null; Context ctx = null;
//If the thread context classloader is set, then try its hierarchy to find a matching context //See if there is a classloader already set to use for finding the comp
//naming Context
ClassLoader loader = (ClassLoader)__threadClassLoader.get();
if (loader != null)
{
if (LOG.isDebugEnabled())
LOG.debug("Using threadlocal classloader");
try (AutoLock l = __lock.lock())
{
ctx = getContextForClassLoader(loader);
if (ctx == null)
{
ctx = newNamingContext(obj, loader, env, name, nameCtx);
__contextMap.put(loader, ctx);
if (LOG.isDebugEnabled())
LOG.debug("Made context {} for classloader {}", name.get(0), loader);
}
return ctx;
}
}
//If the thread context classloader is set, then try it and its
//classloader hierarchy to find a matching naming Context
ClassLoader tccl = Thread.currentThread().getContextClassLoader(); ClassLoader tccl = Thread.currentThread().getContextClassLoader();
ClassLoader loader = tccl; loader = tccl;
if (loader != null) if (loader != null)
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
@ -121,7 +143,7 @@ public class ContextFactory implements ObjectFactory
} }
//If trying thread context classloader hierarchy failed, try the //If trying thread context classloader hierarchy failed, try the
//classloader associated with the current context //classloader associated with the current ContextHandler
if (ContextHandler.getCurrentContext() != null) if (ContextHandler.getCurrentContext() != null)
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
@ -189,6 +211,18 @@ public class ContextFactory implements ObjectFactory
} }
} }
public static ClassLoader associateClassLoader(final ClassLoader loader)
{
ClassLoader prev = (ClassLoader)__threadClassLoader.get();
__threadClassLoader.set(loader);
return prev;
}
public static void disassociateClassLoader()
{
__threadClassLoader.set(null);
}
public static void dump(Appendable out, String indent) throws IOException public static void dump(Appendable out, String indent) throws IOException
{ {
try (AutoLock l = __lock.lock()) try (AutoLock l = __lock.lock())

View File

@ -23,6 +23,7 @@ module org.eclipse.jetty.ee10.plus
// Only required if using Transaction. // Only required if using Transaction.
requires static transitive jakarta.transaction; requires static transitive jakarta.transaction;
requires org.eclipse.jetty.jndi;
exports org.eclipse.jetty.ee10.plus.jndi; exports org.eclipse.jetty.ee10.plus.jndi;
exports org.eclipse.jetty.ee10.plus.webapp; exports org.eclipse.jetty.ee10.plus.webapp;

View File

@ -28,6 +28,7 @@ import org.eclipse.jetty.ee10.webapp.MetaInfConfiguration;
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader; import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
import org.eclipse.jetty.ee10.webapp.WebAppContext; import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.ee10.webapp.WebXmlConfiguration; import org.eclipse.jetty.ee10.webapp.WebXmlConfiguration;
import org.eclipse.jetty.jndi.ContextFactory;
import org.eclipse.jetty.plus.jndi.EnvEntry; import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil; import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.util.jndi.NamingDump; import org.eclipse.jetty.util.jndi.NamingDump;
@ -123,6 +124,7 @@ public class EnvConfiguration extends AbstractConfiguration
//get rid of any bindings for comp/env for webapp //get rid of any bindings for comp/env for webapp
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(context.getClassLoader()); Thread.currentThread().setContextClassLoader(context.getClassLoader());
ContextFactory.associateClassLoader(context.getClassLoader());
try try
{ {
Context ic = new InitialContext(); Context ic = new InitialContext();
@ -147,6 +149,7 @@ public class EnvConfiguration extends AbstractConfiguration
} }
finally finally
{ {
ContextFactory.disassociateClassLoader();
Thread.currentThread().setContextClassLoader(oldLoader); Thread.currentThread().setContextClassLoader(oldLoader);
} }
} }
@ -218,14 +221,26 @@ public class EnvConfiguration extends AbstractConfiguration
{ {
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(wac.getClassLoader()); Thread.currentThread().setContextClassLoader(wac.getClassLoader());
//ensure that we create a unique comp/env context for this webapp based off
//its classloader
ContextFactory.associateClassLoader(wac.getClassLoader());
try try
{ {
Context context = new InitialContext(); WebAppClassLoader.runWithServerClassAccess(() ->
Context compCtx = (Context)context.lookup("java:comp"); {
compCtx.createSubcontext("env"); Context context = new InitialContext();
Context compCtx = (Context)context.lookup("java:comp");
compCtx.createSubcontext("env");
return null;
});
}
catch (Exception e)
{
throw new RuntimeException(e);
} }
finally finally
{ {
ContextFactory.disassociateClassLoader();
Thread.currentThread().setContextClassLoader(oldLoader); Thread.currentThread().setContextClassLoader(oldLoader);
} }
} }

View File

@ -15,7 +15,12 @@ package org.eclipse.jetty.ee10.plus.webapp;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.eclipse.jetty.ee10.webapp.Configuration;
import org.eclipse.jetty.ee10.webapp.WebAppClassLoader;
import org.eclipse.jetty.ee10.webapp.WebAppContext; import org.eclipse.jetty.ee10.webapp.WebAppContext;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil; import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
@ -23,11 +28,16 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Isolated;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@Isolated("jndi entries")
public class EnvConfigurationTest public class EnvConfigurationTest
{ {
Server _server; Server _server;
@ -73,4 +83,79 @@ public class EnvConfigurationTest
assertNotNull(NamingEntryUtil.lookupNamingEntry(context, "peach")); assertNotNull(NamingEntryUtil.lookupNamingEntry(context, "peach"));
assertNull(NamingEntryUtil.lookupNamingEntry(context, "cabbage")); assertNull(NamingEntryUtil.lookupNamingEntry(context, "cabbage"));
} }
@Test
public void testCompEnvCreation() throws Exception
{
EnvConfiguration envConfigurationA = new EnvConfiguration();
EnvConfiguration envConfigurationB = new EnvConfiguration();
WebAppContext webappA = null;
WebAppContext webappB = null;
try
{
webappA = new WebAppContext();
webappA.setConfigurations(new Configuration[]{new PlusConfiguration(), new EnvConfiguration()});
webappA.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), webappA));
//ensure that a java:comp/env Context was created for webappA
envConfigurationA.preConfigure(webappA);
Context namingContextA = getCompEnvFor(webappA);
webappB = new WebAppContext();
webappB.setConfigurations(new Configuration[]{new PlusConfiguration(), new EnvConfiguration()});
webappB.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), webappB));
//ensure that a different java:comp/env Context was created for webappB
envConfigurationB.preConfigure(webappB);
Context namingContextB = getCompEnvFor(webappB);
assertThat(namingContextA, is(not(namingContextB)));
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
envConfigurationA.deconfigure(webappA);
envConfigurationB.deconfigure(webappB);
}
}
@Test
public void testPriorCompCreation() throws Exception
{
//pre-create java:comp on the app classloader
new InitialContext().lookup("java:comp");
//test that each webapp still gets its own naming Context
testCompEnvCreation();
}
/**
* Find the java:comp/env naming Context for the given webapp
* @param webapp the WebAppContext whose naming comp/env Context to find
* @return the comp/env naming Context specific to the given WebAppContext
* @throws NamingException
*/
private Context getCompEnvFor(WebAppContext webapp)
throws NamingException
{
if (webapp == null)
return null;
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Context namingContext = null;
try
{
Thread.currentThread().setContextClassLoader(webapp.getClassLoader());
InitialContext ic = new InitialContext();
namingContext = (Context)ic.lookup("java:comp/env");
return namingContext;
}
finally
{
Thread.currentThread().setContextClassLoader(oldLoader);
}
}
} }

View File

@ -23,6 +23,7 @@ module org.eclipse.jetty.ee11.plus
// Only required if using Transaction. // Only required if using Transaction.
requires static transitive jakarta.transaction; requires static transitive jakarta.transaction;
requires org.eclipse.jetty.jndi;
exports org.eclipse.jetty.ee11.plus.jndi; exports org.eclipse.jetty.ee11.plus.jndi;
exports org.eclipse.jetty.ee11.plus.webapp; exports org.eclipse.jetty.ee11.plus.webapp;

View File

@ -28,6 +28,7 @@ import org.eclipse.jetty.ee11.webapp.MetaInfConfiguration;
import org.eclipse.jetty.ee11.webapp.WebAppClassLoader; import org.eclipse.jetty.ee11.webapp.WebAppClassLoader;
import org.eclipse.jetty.ee11.webapp.WebAppContext; import org.eclipse.jetty.ee11.webapp.WebAppContext;
import org.eclipse.jetty.ee11.webapp.WebXmlConfiguration; import org.eclipse.jetty.ee11.webapp.WebXmlConfiguration;
import org.eclipse.jetty.jndi.ContextFactory;
import org.eclipse.jetty.plus.jndi.EnvEntry; import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil; import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.util.jndi.NamingDump; import org.eclipse.jetty.util.jndi.NamingDump;
@ -122,6 +123,7 @@ public class EnvConfiguration extends AbstractConfiguration
//get rid of any bindings for comp/env for webapp //get rid of any bindings for comp/env for webapp
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(context.getClassLoader()); Thread.currentThread().setContextClassLoader(context.getClassLoader());
ContextFactory.associateClassLoader(context.getClassLoader());
try try
{ {
Context ic = new InitialContext(); Context ic = new InitialContext();
@ -146,6 +148,7 @@ public class EnvConfiguration extends AbstractConfiguration
} }
finally finally
{ {
ContextFactory.disassociateClassLoader();
Thread.currentThread().setContextClassLoader(oldLoader); Thread.currentThread().setContextClassLoader(oldLoader);
} }
} }
@ -217,14 +220,26 @@ public class EnvConfiguration extends AbstractConfiguration
{ {
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(wac.getClassLoader()); Thread.currentThread().setContextClassLoader(wac.getClassLoader());
//ensure that we create a unique comp/env context for this webapp based off
//its classloader
ContextFactory.associateClassLoader(wac.getClassLoader());
try try
{ {
Context context = new InitialContext(); WebAppClassLoader.runWithHiddenClassAccess(() ->
Context compCtx = (Context)context.lookup("java:comp"); {
compCtx.createSubcontext("env"); Context context = new InitialContext();
Context compCtx = (Context)context.lookup("java:comp");
compCtx.createSubcontext("env");
return null;
});
}
catch (Exception e)
{
throw new RuntimeException(e);
} }
finally finally
{ {
ContextFactory.disassociateClassLoader();
Thread.currentThread().setContextClassLoader(oldLoader); Thread.currentThread().setContextClassLoader(oldLoader);
} }
} }

View File

@ -15,7 +15,12 @@ package org.eclipse.jetty.ee11.plus.webapp;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.eclipse.jetty.ee11.webapp.Configuration;
import org.eclipse.jetty.ee11.webapp.WebAppClassLoader;
import org.eclipse.jetty.ee11.webapp.WebAppContext; import org.eclipse.jetty.ee11.webapp.WebAppContext;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil; import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
@ -23,11 +28,16 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Isolated;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@Isolated("jndi entries")
public class EnvConfigurationTest public class EnvConfigurationTest
{ {
Server _server; Server _server;
@ -73,4 +83,79 @@ public class EnvConfigurationTest
assertNotNull(NamingEntryUtil.lookupNamingEntry(context, "peach")); assertNotNull(NamingEntryUtil.lookupNamingEntry(context, "peach"));
assertNull(NamingEntryUtil.lookupNamingEntry(context, "cabbage")); assertNull(NamingEntryUtil.lookupNamingEntry(context, "cabbage"));
} }
@Test
public void testCompEnvCreation() throws Exception
{
EnvConfiguration envConfigurationA = new EnvConfiguration();
EnvConfiguration envConfigurationB = new EnvConfiguration();
WebAppContext webappA = null;
WebAppContext webappB = null;
try
{
webappA = new WebAppContext();
webappA.setConfigurations(new Configuration[]{new PlusConfiguration(), new EnvConfiguration()});
webappA.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), webappA));
//ensure that a java:comp/env Context was created for webappA
envConfigurationA.preConfigure(webappA);
Context namingContextA = getCompEnvFor(webappA);
webappB = new WebAppContext();
webappB.setConfigurations(new Configuration[]{new PlusConfiguration(), new EnvConfiguration()});
webappB.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), webappB));
//ensure that a different java:comp/env Context was created for webappB
envConfigurationB.preConfigure(webappB);
Context namingContextB = getCompEnvFor(webappB);
assertThat(namingContextA, is(not(namingContextB)));
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
envConfigurationA.deconfigure(webappA);
envConfigurationB.deconfigure(webappB);
}
}
@Test
public void testPriorCompCreation() throws Exception
{
//pre-create java:comp on the app classloader
new InitialContext().lookup("java:comp");
//test that each webapp still gets its own naming Context
testCompEnvCreation();
}
/**
* Find the java:comp/env naming Context for the given webapp
* @param webapp the WebAppContext whose naming comp/env Context to find
* @return the comp/env naming Context specific to the given WebAppContext
* @throws NamingException
*/
private Context getCompEnvFor(WebAppContext webapp)
throws NamingException
{
if (webapp == null)
return null;
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Context namingContext = null;
try
{
Thread.currentThread().setContextClassLoader(webapp.getClassLoader());
InitialContext ic = new InitialContext();
namingContext = (Context)ic.lookup("java:comp/env");
return namingContext;
}
finally
{
Thread.currentThread().setContextClassLoader(oldLoader);
}
}
} }

View File

@ -24,6 +24,7 @@ module org.eclipse.jetty.ee9.plus
// Only required if using Transaction. // Only required if using Transaction.
requires static transitive jakarta.transaction; requires static transitive jakarta.transaction;
requires org.eclipse.jetty.jndi;
exports org.eclipse.jetty.ee9.plus.jndi; exports org.eclipse.jetty.ee9.plus.jndi;
exports org.eclipse.jetty.ee9.plus.webapp; exports org.eclipse.jetty.ee9.plus.webapp;

View File

@ -29,6 +29,7 @@ import org.eclipse.jetty.ee9.webapp.MetaInfConfiguration;
import org.eclipse.jetty.ee9.webapp.WebAppClassLoader; import org.eclipse.jetty.ee9.webapp.WebAppClassLoader;
import org.eclipse.jetty.ee9.webapp.WebAppContext; import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.ee9.webapp.WebXmlConfiguration; import org.eclipse.jetty.ee9.webapp.WebXmlConfiguration;
import org.eclipse.jetty.jndi.ContextFactory;
import org.eclipse.jetty.plus.jndi.EnvEntry; import org.eclipse.jetty.plus.jndi.EnvEntry;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil; import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.IO;
@ -139,6 +140,7 @@ public class EnvConfiguration extends AbstractConfiguration
//get rid of any bindings for comp/env for webapp //get rid of any bindings for comp/env for webapp
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(context.getClassLoader()); Thread.currentThread().setContextClassLoader(context.getClassLoader());
ContextFactory.associateClassLoader(context.getClassLoader());
try try
{ {
Context ic = new InitialContext(); Context ic = new InitialContext();
@ -163,6 +165,7 @@ public class EnvConfiguration extends AbstractConfiguration
} }
finally finally
{ {
ContextFactory.disassociateClassLoader();
Thread.currentThread().setContextClassLoader(oldLoader); Thread.currentThread().setContextClassLoader(oldLoader);
IO.close(_resourceFactory); IO.close(_resourceFactory);
_resourceFactory = null; _resourceFactory = null;
@ -236,14 +239,27 @@ public class EnvConfiguration extends AbstractConfiguration
{ {
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(wac.getClassLoader()); Thread.currentThread().setContextClassLoader(wac.getClassLoader());
//ensure that we create a unique comp/env context for this webapp based off
//its classloader
ContextFactory.associateClassLoader(wac.getClassLoader());
try try
{ {
Context context = new InitialContext(); WebAppClassLoader.runWithServerClassAccess(() ->
Context compCtx = (Context)context.lookup("java:comp"); {
compCtx.createSubcontext("env"); Context context = new InitialContext();
Context compCtx = (Context)context.lookup("java:comp");
compCtx.createSubcontext("env");
return null;
});
}
catch (Exception e)
{
throw new RuntimeException(e);
} }
finally finally
{ {
ContextFactory.disassociateClassLoader();
Thread.currentThread().setContextClassLoader(oldLoader); Thread.currentThread().setContextClassLoader(oldLoader);
} }
} }

View File

@ -15,20 +15,29 @@ package org.eclipse.jetty.ee9.plus.webapp;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.eclipse.jetty.ee9.webapp.Configuration;
import org.eclipse.jetty.ee9.webapp.WebAppClassLoader;
import org.eclipse.jetty.ee9.webapp.WebAppContext; import org.eclipse.jetty.ee9.webapp.WebAppContext;
import org.eclipse.jetty.plus.jndi.NamingEntryUtil; import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.jndi.NamingUtil;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Isolated;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@Isolated("jndi entries")
public class EnvConfigurationTest public class EnvConfigurationTest
{ {
Server _server; Server _server;
@ -74,4 +83,74 @@ public class EnvConfigurationTest
assertNotNull(NamingEntryUtil.lookupNamingEntry(context, "peach")); assertNotNull(NamingEntryUtil.lookupNamingEntry(context, "peach"));
assertNull(NamingEntryUtil.lookupNamingEntry(context, "cabbage")); assertNull(NamingEntryUtil.lookupNamingEntry(context, "cabbage"));
} }
@Test
public void testCompEnvCreation() throws Exception
{
EnvConfiguration envConfigurationA = new EnvConfiguration();
EnvConfiguration envConfigurationB = new EnvConfiguration();
WebAppContext webappA = null;
WebAppContext webappB = null;
try
{
webappA = new WebAppContext();
webappA.setConfigurations(new Configuration[]{new PlusConfiguration(), new EnvConfiguration()});
webappA.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), webappA));
//ensure that a java:comp/env Context was created for webappA
envConfigurationA.preConfigure(webappA);
Context namingContextA = getCompEnvFor(webappA);
webappB = new WebAppContext();
webappB.setConfigurations(new Configuration[]{new PlusConfiguration(), new EnvConfiguration()});
webappB.setClassLoader(new WebAppClassLoader(Thread.currentThread().getContextClassLoader(), webappB));
//ensure that a different java:comp/env Context was created for webappB
envConfigurationB.preConfigure(webappB);
Context namingContextB = getCompEnvFor(webappB);
assertThat(namingContextA, is(not(namingContextB)));
}
finally
{
envConfigurationA.deconfigure(webappA);
envConfigurationB.deconfigure(webappB);
}
}
@Test
public void testPriorCompCreation() throws Exception
{
//pre-create java:comp on the app classloader
new InitialContext().lookup("java:comp");
//test that each webapp still gets its own naming Context
testCompEnvCreation();
}
/**
* Find the java:comp/env naming Context for the given webapp
* @param webapp the WebAppContext whose naming comp/env Context to find
* @return the comp/env naming Context specific to the given WebAppContext
* @throws NamingException
*/
private Context getCompEnvFor(WebAppContext webapp)
throws NamingException
{
if (webapp == null)
return null;
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
Context namingContext = null;
try
{
Thread.currentThread().setContextClassLoader(webapp.getClassLoader());
InitialContext ic = new InitialContext();
namingContext = (Context)ic.lookup("java:comp/env");
return namingContext;
}
finally
{
Thread.currentThread().setContextClassLoader(oldLoader);
}
}
} }