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.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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue