Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.1.x
This commit is contained in:
commit
8c276f54d0
|
@ -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())
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue