Issue #3729 concurrent JNDI access
+ made locking deep Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
7484651941
commit
4db934a809
|
@ -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?" ":" | "));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue