Issue #3729 concurrent JNDI access

+ made locking deep

Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
Greg Wilkins 2019-06-05 12:00:32 +02:00
parent 7484651941
commit 4db934a809
3 changed files with 36 additions and 37 deletions

View File

@ -20,7 +20,6 @@ package org.eclipse.jetty.jndi;
import java.io.IOException; import java.io.IOException;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.Name; import javax.naming.Name;
@ -30,6 +29,7 @@ import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory; import javax.naming.spi.ObjectFactory;
import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Logger; 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 public static void dump(Appendable out, String indent) throws IOException
{ {
out.append("o.e.j.jndi.ContextFactory@").append(Long.toHexString(__contextMap.hashCode())).append("\n"); Dumpable.dumpObjects(out, indent, String.format("o.e.j.jndi.ContextFactory@",__contextMap.hashCode()), __contextMap);
int size=__contextMap.size();
int i=0;
for (Map.Entry<ClassLoader,NamingContext> entry : ((Map<ClassLoader,NamingContext>)__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?" ":" | "));
}
} }
} }

View File

@ -84,6 +84,7 @@ public class NamingContext implements Context, Dumpable
protected String _name = null; protected String _name = null;
protected NameParser _parser = null; protected NameParser _parser = null;
private Collection<Listener> _listeners; private Collection<Listener> _listeners;
private Object _lock;
/*------------------------------------------------*/ /*------------------------------------------------*/
/** /**
@ -190,13 +191,21 @@ public class NamingContext implements Context, Dumpable
_parser = parser; _parser = parser;
} }
public final void setEnv (Hashtable<String,Object> env) public final void setEnv (Hashtable<String,Object> env)
{ {
_env.clear(); Object lock = _env.get(LOCK_PROPERTY);
if(env == null) try
return; {
_env.putAll(env); _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 private Object dereference(Object ctx, String firstComponent) throws NamingException
@ -888,7 +897,6 @@ public class NamingContext implements Context, Dumpable
return _parser; return _parser;
} }
/*------------------------------------------------*/ /*------------------------------------------------*/
/** /**
* Get the full name of this Context node * Get the full name of this Context node
@ -917,7 +925,6 @@ public class NamingContext implements Context, Dumpable
return name.toString(); return name.toString();
} }
/*------------------------------------------------*/ /*------------------------------------------------*/
/** /**
* Add an environment setting to this Context * Add an environment setting to this Context
@ -932,13 +939,25 @@ public class NamingContext implements Context, Dumpable
Object propVal) Object propVal)
throws NamingException throws NamingException
{ {
if (isLocked() && !(propName.equals(UNLOCK_PROPERTY))) switch(propName)
throw new NamingException ("This context is immutable"); {
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. * Remove a property from this Context's environment.
@ -1080,18 +1099,9 @@ public class NamingContext implements Context, Dumpable
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public boolean isLocked() public boolean isLocked()
{ {
if ((_env.get(LOCK_PROPERTY) == null) && (_env.get(UNLOCK_PROPERTY) == null)) return _lock != null || (_parent!=null && _parent.isLocked());
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;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public String dump() public String dump()

View File

@ -19,11 +19,11 @@
package org.eclipse.jetty.plus.webapp; package org.eclipse.jetty.plus.webapp;
import java.util.Random; import java.util.Random;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.InitialContext; import javax.naming.InitialContext;
import javax.naming.NameNotFoundException; import javax.naming.NameNotFoundException;
import org.eclipse.jetty.jndi.NamingContext;
import org.eclipse.jetty.plus.annotation.InjectionCollection; import org.eclipse.jetty.plus.annotation.InjectionCollection;
import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection; import org.eclipse.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.eclipse.jetty.plus.jndi.Transaction; import org.eclipse.jetty.plus.jndi.Transaction;
@ -106,10 +106,10 @@ public class PlusConfiguration extends AbstractConfiguration
try try
{ {
Random random = new Random (); Random random = new Random ();
_key = new Integer(random.nextInt()); _key = random.nextInt();
Context context = new InitialContext(); Context context = new InitialContext();
Context compCtx = (Context)context.lookup("java:comp"); Context compCtx = (Context)context.lookup("java:comp");
compCtx.addToEnvironment("org.eclipse.jetty.jndi.lock", _key); compCtx.addToEnvironment(NamingContext.LOCK_PROPERTY, _key);
} }
finally finally
{ {