From 04d8dc664fbc231f69cc6e75b7ceac024249db9c Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 20 Sep 2012 16:47:00 +1000 Subject: [PATCH] 389956 Bad __context set in WebAppContext.start sequence with respect to ENC setup --- .../eclipse/jetty/jndi/ContextFactory.java | 73 ++++---------- .../org/eclipse/jetty/jndi/java/TestJNDI.java | 96 +++++++++++++++++-- 2 files changed, 106 insertions(+), 63 deletions(-) diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java index 498a3510254..75ce5b4efb9 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java @@ -99,74 +99,41 @@ public class ContextFactory implements ObjectFactory return ctx; } - // Next, see if we are in a webapp context, if we are, use - // the classloader of the webapp to find the right jndi comp context ClassLoader loader = null; - if (ContextHandler.getCurrentContext() != null) + + loader = Thread.currentThread().getContextClassLoader(); + if (__log.isDebugEnabled() && loader != null) __log.debug("Using thread context classloader"); + + if (loader == null && ContextHandler.getCurrentContext() != null) { loader = ContextHandler.getCurrentContext().getContextHandler().getClassLoader(); + if (__log.isDebugEnabled() && loader != null) __log.debug("Using classloader of current org.eclipse.jetty.server.handler.ContextHandler"); } - - - if (loader != null) - { - if (__log.isDebugEnabled()) __log.debug("Using classloader of current org.eclipse.jetty.server.handler.ContextHandler"); - } - else - { - //Not already in a webapp context, in that case, we try the - //curren't thread's classloader instead - loader = Thread.currentThread().getContextClassLoader(); - if (__log.isDebugEnabled()) __log.debug("Using thread context classloader"); - } - + //Get the context matching the classloader ctx = (Context)__contextMap.get(loader); - + //The map does not contain an entry for this classloader if (ctx == null) { - //Check if a parent classloader has created the context - ctx = getParentClassLoaderContext(loader); + //Didn't find a context to match, make one + Reference ref = (Reference)obj; + StringRefAddr parserAddr = (StringRefAddr)ref.get("parser"); + String parserClassName = (parserAddr==null?null:(String)parserAddr.getContent()); + NameParser parser = (NameParser)(parserClassName==null?null:loader.loadClass(parserClassName).newInstance()); - //Didn't find a context to match any of the ancestors - //of the classloader, so make a context - if (ctx == null) - { - Reference ref = (Reference)obj; - StringRefAddr parserAddr = (StringRefAddr)ref.get("parser"); - String parserClassName = (parserAddr==null?null:(String)parserAddr.getContent()); - NameParser parser = (NameParser)(parserClassName==null?null:loader.loadClass(parserClassName).newInstance()); - - ctx = new NamingContext (env, - name.get(0), - (NamingContext)nameCtx, - parser); - if(__log.isDebugEnabled())__log.debug("No entry for classloader: "+loader); - __contextMap.put (loader, ctx); - } + ctx = new NamingContext (env, + name.get(0), + (NamingContext)nameCtx, + parser); + if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+loader); + __contextMap.put (loader, ctx); } return ctx; } - /** - * Keep trying ancestors of the given classloader to find one to which - * the context is bound. - * @param loader - * @return the context from the parent class loader - */ - public Context getParentClassLoaderContext (ClassLoader loader) - { - Context ctx = null; - ClassLoader cl = loader; - for (cl = cl.getParent(); (cl != null) && (ctx == null); cl = cl.getParent()) - { - ctx = (Context)__contextMap.get(cl); - } - - return ctx; - } + /** diff --git a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java index b30f076b765..6cbfb065a5f 100644 --- a/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java +++ b/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java @@ -37,6 +37,7 @@ import javax.naming.Reference; import javax.naming.StringRefAddr; import javax.naming.spi.ObjectFactory; +import org.eclipse.jetty.jndi.ContextFactory; import org.eclipse.jetty.jndi.NamingContext; import org.eclipse.jetty.jndi.NamingUtil; import org.eclipse.jetty.jndi.local.localContextRoot; @@ -47,7 +48,8 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; - +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; /** * */ @@ -74,14 +76,16 @@ public class TestJNDI @Test public void testIt() throws Exception { + //set up some classloaders + Thread currentThread = Thread.currentThread(); + ClassLoader currentLoader = currentThread.getContextClassLoader(); + ClassLoader childLoader1 = new URLClassLoader(new URL[0], currentLoader); + ClassLoader childLoader2 = new URLClassLoader(new URL[0], currentLoader); + try { - //set up some classloaders - Thread currentThread = Thread.currentThread(); - ClassLoader currentLoader = currentThread.getContextClassLoader(); - ClassLoader childLoader1 = new URLClassLoader(new URL[0], currentLoader); - ClassLoader childLoader2 = new URLClassLoader(new URL[0], currentLoader); + //Uncomment to aid with debug /* javaRootURLContext.getRoot().addListener(new NamingContext.Listener() { @@ -119,7 +123,19 @@ public class TestJNDI InitialContext initCtxA = new InitialContext(); initCtxA.bind ("blah", "123"); assertEquals ("123", initCtxA.lookup("blah")); - + + initCtxA.destroySubcontext("blah"); + try + { + initCtxA.lookup("blah"); + fail("context blah was not destroyed"); + } + catch (NameNotFoundException e) + { + //expected + } + + InitialContext initCtx = new InitialContext(); Context sub0 = (Context)initCtx.lookup("java:"); @@ -219,6 +235,7 @@ public class TestJNDI try { initCtx.lookup("java:comp/env/rubbish"); + fail("env should not exist for this classloader"); } catch (NameNotFoundException e) { @@ -287,18 +304,77 @@ public class TestJNDI { //expected failure to modify immutable context } - - System.err.println("java:"+javaRootURLContext.getRoot().dump()); - System.err.println("local:"+localContextRoot.getRoot().dump()); //test what happens when you close an initial context that was used initCtx.close(); } finally { + //make some effort to clean up InitialContext ic = new InitialContext(); + Context java = (Context)ic.lookup("java:"); + java.destroySubcontext("zero"); + java.destroySubcontext("fee"); + currentThread.setContextClassLoader(childLoader1); Context comp = (Context)ic.lookup("java:comp"); comp.destroySubcontext("env"); + comp.unbind("crud"); + comp.unbind("crud2"); + } + } + + + @Test + public void testParent() + throws Exception + { + //set up some classloaders + Thread currentThread = Thread.currentThread(); + ClassLoader parentLoader = currentThread.getContextClassLoader(); + ClassLoader childLoader1 = new URLClassLoader(new URL[0], parentLoader); + + try + { + //Test creating a comp for the parent loader does not leak to child + InitialContext initCtx = new InitialContext(); + Context comp = (Context)initCtx.lookup("java:comp"); + assertNotNull(comp); + + Context env = (Context)comp.createSubcontext("env"); + assertNotNull(env); + + env.bind("foo", "aaabbbcccddd"); + assertEquals("aaabbbcccddd", (String)initCtx.lookup("java:comp/env/foo")); + + //Change to child loader + currentThread.setContextClassLoader(childLoader1); + comp = (Context)initCtx.lookup("java:comp"); + + Context childEnv = (Context)comp.createSubcontext("env"); + assertNotSame(env, childEnv); + + childEnv.bind("foo", "eeefffggghhh"); + assertEquals("eeefffggghhh", (String)initCtx.lookup("java:comp/env/foo")); + + //Change back to parent + currentThread.setContextClassLoader(parentLoader); + assertEquals("aaabbbcccddd", (String)initCtx.lookup("java:comp/env/foo")); + + + } + finally + { + //make some effort to clean up + InitialContext ic = new InitialContext(); + currentThread.setContextClassLoader(parentLoader); + Context comp = (Context)ic.lookup("java:comp"); + comp.destroySubcontext("env"); + + currentThread.setContextClassLoader(childLoader1); + comp = (Context)ic.lookup("java:comp"); + comp.destroySubcontext("env"); + + } } }