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.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<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?" ":" | "));
}
Dumpable.dumpObjects(out, indent, String.format("o.e.j.jndi.ContextFactory@",__contextMap.hashCode()), __contextMap);
}
}

View File

@ -84,6 +84,7 @@ public class NamingContext implements Context, Dumpable
protected String _name = null;
protected NameParser _parser = null;
private Collection<Listener> _listeners;
private Object _lock;
/*------------------------------------------------*/
/**
@ -190,13 +191,21 @@ public class NamingContext implements Context, Dumpable
_parser = parser;
}
public final void setEnv (Hashtable<String,Object> 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()

View File

@ -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
{