From 4db934a8099c8ea0b01cde24b2e4dc1ec83171e1 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 5 Jun 2019 12:00:32 +0200 Subject: [PATCH] Issue #3729 concurrent JNDI access + made locking deep Signed-off-by: Greg Wilkins --- .../eclipse/jetty/jndi/ContextFactory.java | 15 +----- .../org/eclipse/jetty/jndi/NamingContext.java | 52 +++++++++++-------- .../jetty/plus/webapp/PlusConfiguration.java | 6 +-- 3 files changed, 36 insertions(+), 37 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 a6a0666fc62..8be6d80d577 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 @@ -20,7 +20,6 @@ package org.eclipse.jetty.jndi; import java.io.IOException; import java.util.Hashtable; -import java.util.Map; import java.util.WeakHashMap; import javax.naming.Context; import javax.naming.Name; @@ -30,6 +29,7 @@ import javax.naming.StringRefAddr; import javax.naming.spi.ObjectFactory; import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Logger; @@ -239,17 +239,6 @@ public class ContextFactory implements ObjectFactory public static void dump(Appendable out, String indent) throws IOException { - out.append("o.e.j.jndi.ContextFactory@").append(Long.toHexString(__contextMap.hashCode())).append("\n"); - int size=__contextMap.size(); - int i=0; - for (Map.Entry entry : ((Map)__contextMap).entrySet()) - { - boolean last=++i==size; - ClassLoader loader=entry.getKey(); - out.append(indent).append(" +- ").append(loader.getClass().getSimpleName()).append("@").append(Long.toHexString(loader.hashCode())).append(": "); - - NamingContext context = entry.getValue(); - context.dump(out,indent+(last?" ":" | ")); - } + Dumpable.dumpObjects(out, indent, String.format("o.e.j.jndi.ContextFactory@",__contextMap.hashCode()), __contextMap); } } diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java index e694d247e55..4fb11636393 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java @@ -84,6 +84,7 @@ public class NamingContext implements Context, Dumpable protected String _name = null; protected NameParser _parser = null; private Collection _listeners; + private Object _lock; /*------------------------------------------------*/ /** @@ -190,13 +191,21 @@ public class NamingContext implements Context, Dumpable _parser = parser; } - public final void setEnv (Hashtable env) { - _env.clear(); - if(env == null) - return; - _env.putAll(env); + Object lock = _env.get(LOCK_PROPERTY); + try + { + _env.clear(); + if (env == null) + return; + _env.putAll(env); + } + finally + { + if (lock!=null) + _env.put(LOCK_PROPERTY, lock); + } } private Object dereference(Object ctx, String firstComponent) throws NamingException @@ -888,7 +897,6 @@ public class NamingContext implements Context, Dumpable return _parser; } - /*------------------------------------------------*/ /** * Get the full name of this Context node @@ -917,7 +925,6 @@ public class NamingContext implements Context, Dumpable return name.toString(); } - /*------------------------------------------------*/ /** * Add an environment setting to this Context @@ -932,13 +939,25 @@ public class NamingContext implements Context, Dumpable Object propVal) throws NamingException { - if (isLocked() && !(propName.equals(UNLOCK_PROPERTY))) - throw new NamingException ("This context is immutable"); + switch(propName) + { + case LOCK_PROPERTY: + if (_lock == null) + _lock = propVal; + return null; - return _env.put (propName, propVal); + case UNLOCK_PROPERTY: + if (propVal != null && propVal.equals(_lock)) + _lock = null; + return null; + + default: + if (isLocked()) + throw new NamingException("This context is immutable"); + return _env.put(propName, propVal); + } } - /*------------------------------------------------*/ /** * Remove a property from this Context's environment. @@ -1080,18 +1099,9 @@ public class NamingContext implements Context, Dumpable /* ------------------------------------------------------------ */ public boolean isLocked() { - if ((_env.get(LOCK_PROPERTY) == null) && (_env.get(UNLOCK_PROPERTY) == null)) - return false; - - Object lockKey = _env.get(LOCK_PROPERTY); - Object unlockKey = _env.get(UNLOCK_PROPERTY); - - if ((lockKey != null) && (unlockKey != null) && (lockKey.equals(unlockKey))) - return false; - return true; + return _lock != null || (_parent!=null && _parent.isLocked()); } - /* ------------------------------------------------------------ */ @Override public String dump() diff --git a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusConfiguration.java b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusConfiguration.java index af6d2baaf54..c04df74445f 100644 --- a/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusConfiguration.java +++ b/jetty-plus/src/main/java/org/eclipse/jetty/plus/webapp/PlusConfiguration.java @@ -19,11 +19,11 @@ package org.eclipse.jetty.plus.webapp; import java.util.Random; - import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameNotFoundException; +import org.eclipse.jetty.jndi.NamingContext; import org.eclipse.jetty.plus.annotation.InjectionCollection; import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection; import org.eclipse.jetty.plus.jndi.Transaction; @@ -106,10 +106,10 @@ public class PlusConfiguration extends AbstractConfiguration try { Random random = new Random (); - _key = new Integer(random.nextInt()); + _key = random.nextInt(); Context context = new InitialContext(); Context compCtx = (Context)context.lookup("java:comp"); - compCtx.addToEnvironment("org.eclipse.jetty.jndi.lock", _key); + compCtx.addToEnvironment(NamingContext.LOCK_PROPERTY, _key); } finally {