Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'.
This commit is contained in:
commit
bf53925cfb
|
@ -18,12 +18,11 @@
|
|||
|
||||
package org.eclipse.jetty.jndi;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NameParser;
|
||||
|
@ -32,6 +31,8 @@ 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.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
|
@ -59,12 +60,12 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*/
|
||||
public class ContextFactory implements ObjectFactory
|
||||
{
|
||||
private static Logger __log = NamingUtil.__log;
|
||||
private static final Logger LOG = Log.getLogger(ContextFactory.class);
|
||||
|
||||
/**
|
||||
* Map of classloaders to contexts.
|
||||
*/
|
||||
private static final WeakHashMap __contextMap = new WeakHashMap();
|
||||
private static final Map<ClassLoader, Context> __contextMap = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
|
||||
/**
|
||||
* Threadlocal for injecting a context to use
|
||||
|
@ -77,8 +78,6 @@ public class ContextFactory implements ObjectFactory
|
|||
* when finding the comp context.
|
||||
*/
|
||||
private static final ThreadLocal<ClassLoader> __threadClassLoader = new ThreadLocal<ClassLoader>();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find or create a context which pertains to a classloader.
|
||||
|
@ -106,7 +105,8 @@ public class ContextFactory implements ObjectFactory
|
|||
Context ctx = (Context)__threadContext.get();
|
||||
if (ctx != null)
|
||||
{
|
||||
if(__log.isDebugEnabled()) __log.debug("Using the Context that is bound on the thread");
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Using the Context that is bound on the thread");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
@ -115,37 +115,47 @@ public class ContextFactory implements ObjectFactory
|
|||
ClassLoader loader = (ClassLoader)__threadClassLoader.get();
|
||||
if (loader != null)
|
||||
{
|
||||
if (__log.isDebugEnabled() && loader != null) __log.debug("Using threadlocal classloader");
|
||||
ctx = getContextForClassLoader(loader);
|
||||
if (ctx == null)
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Using threadlocal classloader");
|
||||
synchronized(__contextMap)
|
||||
{
|
||||
ctx = newNamingContext(obj, loader, env, name, nameCtx);
|
||||
__contextMap.put (loader, ctx);
|
||||
if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+loader);
|
||||
ctx = getContextForClassLoader(loader);
|
||||
if (ctx == null)
|
||||
{
|
||||
ctx = newNamingContext(obj, loader, env, name, nameCtx);
|
||||
__contextMap.put (loader, ctx);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Made context {} for classloader {}",name.get(0),loader);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
//If the thread context classloader is set, then try its hierarchy to find a matching context
|
||||
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
|
||||
loader = tccl;
|
||||
if (loader != null)
|
||||
{
|
||||
if (__log.isDebugEnabled() && loader != null) __log.debug("Trying thread context classloader");
|
||||
while (ctx == null && loader != null)
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Trying thread context classloader");
|
||||
synchronized(__contextMap)
|
||||
{
|
||||
ctx = getContextForClassLoader(loader);
|
||||
if (ctx == null && loader != null)
|
||||
loader = loader.getParent();
|
||||
}
|
||||
while (ctx == null && loader != null)
|
||||
{
|
||||
ctx = getContextForClassLoader(loader);
|
||||
if (ctx == null && loader != null)
|
||||
loader = loader.getParent();
|
||||
}
|
||||
|
||||
if (ctx == null)
|
||||
{
|
||||
ctx = newNamingContext(obj, tccl, env, name, nameCtx);
|
||||
__contextMap.put (tccl, ctx);
|
||||
if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+tccl);
|
||||
if (ctx == null)
|
||||
{
|
||||
ctx = newNamingContext(obj, tccl, env, name, nameCtx);
|
||||
__contextMap.put (tccl, ctx);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Made context {} for classloader {}", name.get(0), tccl);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,19 +163,23 @@ public class ContextFactory implements ObjectFactory
|
|||
//classloader associated with the current context
|
||||
if (ContextHandler.getCurrentContext() != null)
|
||||
{
|
||||
|
||||
if (__log.isDebugEnabled() && loader != null) __log.debug("Trying classloader of current org.eclipse.jetty.server.handler.ContextHandler");
|
||||
loader = ContextHandler.getCurrentContext().getContextHandler().getClassLoader();
|
||||
ctx = (Context)__contextMap.get(loader);
|
||||
|
||||
if (ctx == null && loader != null)
|
||||
if (LOG.isDebugEnabled() && loader != null)
|
||||
LOG.debug("Trying classloader of current org.eclipse.jetty.server.handler.ContextHandler");
|
||||
synchronized(__contextMap)
|
||||
{
|
||||
ctx = newNamingContext(obj, loader, env, name, nameCtx);
|
||||
__contextMap.put (loader, ctx);
|
||||
if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+loader);
|
||||
}
|
||||
loader = ContextHandler.getCurrentContext().getContextHandler().getClassLoader();
|
||||
ctx = (Context)__contextMap.get(loader);
|
||||
|
||||
return ctx;
|
||||
if (ctx == null && loader != null)
|
||||
{
|
||||
ctx = newNamingContext(obj, loader, env, name, nameCtx);
|
||||
__contextMap.put (loader, ctx);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Made context {} for classloader {} ", name.get(0), loader);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -243,17 +257,9 @@ 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())
|
||||
synchronized (__contextMap)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.jndi;
|
||||
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.naming.CompoundName;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
|
@ -29,6 +27,7 @@ import javax.naming.NameParser;
|
|||
import javax.naming.NamingException;
|
||||
|
||||
import org.eclipse.jetty.jndi.local.localContextRoot;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
|
@ -44,7 +43,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*/
|
||||
public class InitialContextFactory implements javax.naming.spi.InitialContextFactory
|
||||
{
|
||||
private static Logger __log = NamingUtil.__log;
|
||||
private static final Logger LOG = Log.getLogger(InitialContextFactory.class);
|
||||
|
||||
public static class DefaultParser implements NameParser
|
||||
{
|
||||
|
@ -78,10 +77,12 @@ public class InitialContextFactory implements javax.naming.spi.InitialContextFac
|
|||
@Override
|
||||
public Context getInitialContext(Hashtable env)
|
||||
{
|
||||
__log.debug("InitialContextFactory.getInitialContext()");
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("InitialContextFactory.getInitialContext()");
|
||||
|
||||
Context ctx = new localContextRoot(env);
|
||||
if(__log.isDebugEnabled())__log.debug("Created initial context delegate for local namespace:"+ctx);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Created initial context delegate for local namespace:"+ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
|
|
@ -22,11 +22,10 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.CompoundName;
|
||||
import javax.naming.Context;
|
||||
|
@ -45,6 +44,7 @@ import javax.naming.Referenceable;
|
|||
import javax.naming.spi.NamingManager;
|
||||
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
|
@ -56,22 +56,36 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
* All Names are expected to be Compound, not Composite.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class NamingContext implements Context, Cloneable, Dumpable
|
||||
public class NamingContext implements Context, Dumpable
|
||||
{
|
||||
private final static Logger __log=NamingUtil.__log;
|
||||
private static final Logger LOG = Log.getLogger(NamingContext.class);
|
||||
private final static List<Binding> __empty = Collections.emptyList();
|
||||
public static final String DEEP_BINDING = "org.eclipse.jetty.jndi.deepBinding";
|
||||
public static final String LOCK_PROPERTY = "org.eclipse.jetty.jndi.lock";
|
||||
public static final String UNLOCK_PROPERTY = "org.eclipse.jetty.jndi.unlock";
|
||||
|
||||
protected final Hashtable<String,Object> _env = new Hashtable<String,Object>();
|
||||
private boolean _supportDeepBinding = false;
|
||||
protected Map<String,Binding> _bindings = new HashMap<String,Binding>();
|
||||
/*
|
||||
* The env is stored as a Hashtable to be compatible with the API.
|
||||
* There is no need for concurrent protection (see Concurrent Access section
|
||||
* of the {@link Context} javadoc), so multiple threads acting on the same
|
||||
* Context env need to self - mutually exclude.
|
||||
*/
|
||||
protected final Hashtable<String,Object> _env = new Hashtable<>();
|
||||
|
||||
/*
|
||||
* This contexts bindings are stored as a ConcurrentHashMap.
|
||||
* There is generally no need for concurrent protection (see Concurrent Access section
|
||||
* of the {@link Context} javadoc), However, the NamingContext is used for root contexts and
|
||||
* we do not mutually exclude when initializing, so instead we do make the bindings
|
||||
* thread safe (unlike the env where we expect users to respect the Concurrent Access requirements).
|
||||
*/
|
||||
protected final ConcurrentMap<String,Binding> _bindings;
|
||||
|
||||
protected NamingContext _parent = null;
|
||||
protected String _name = null;
|
||||
protected NameParser _parser = null;
|
||||
private Collection<Listener> _listeners;
|
||||
private Object _lock;
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
|
@ -99,7 +113,7 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param env environment properties
|
||||
* @param env environment properties which are copied into this Context's environment
|
||||
* @param name relative name of this context
|
||||
* @param parent immediate ancestor Context (can be null)
|
||||
* @param parser NameParser for this Context
|
||||
|
@ -108,53 +122,48 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
String name,
|
||||
NamingContext parent,
|
||||
NameParser parser)
|
||||
{
|
||||
this(env, name, parent, parser, null);
|
||||
}
|
||||
|
||||
private NamingContext(Hashtable<String,Object> env,
|
||||
String name,
|
||||
NamingContext parent,
|
||||
NameParser parser,
|
||||
ConcurrentMap<String, Binding> bindings)
|
||||
{
|
||||
if (env != null)
|
||||
{
|
||||
_env.putAll(env);
|
||||
// look for deep binding support in _env
|
||||
Object support = _env.get(DEEP_BINDING);
|
||||
if (support == null)
|
||||
_supportDeepBinding = false;
|
||||
else
|
||||
_supportDeepBinding = support != null?Boolean.parseBoolean(support.toString()):false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no env? likely this is a root context (java or local) that
|
||||
// was created without an _env. Look for a system property.
|
||||
String value = System.getProperty(DEEP_BINDING,"false");
|
||||
_supportDeepBinding = Boolean.parseBoolean(value);
|
||||
// put what we discovered into the _env for later sub-contexts
|
||||
// to utilize.
|
||||
_env.put(DEEP_BINDING,_supportDeepBinding);
|
||||
}
|
||||
_name = name;
|
||||
_parent = parent;
|
||||
_parser = parser;
|
||||
if(__log.isDebugEnabled())
|
||||
__log.debug("supportDeepBinding={}",_supportDeepBinding);
|
||||
_bindings = bindings==null ? new ConcurrentHashMap<>() : bindings;
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("new {}", this);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Clone this NamingContext
|
||||
*
|
||||
* @return copy of this NamingContext
|
||||
* @exception CloneNotSupportedException if an error occurs
|
||||
* @return A shallow copy of the Context with the same bindings, but a copy of the Env
|
||||
*/
|
||||
@Override
|
||||
public Object clone ()
|
||||
throws CloneNotSupportedException
|
||||
public NamingContext shallowCopy()
|
||||
{
|
||||
NamingContext ctx = (NamingContext)super.clone();
|
||||
ctx._env.putAll(_env);
|
||||
ctx._bindings.putAll(_bindings);
|
||||
return ctx;
|
||||
return new NamingContext(_env, _name, _parent, _parser, _bindings);
|
||||
}
|
||||
|
||||
|
||||
public boolean isDeepBindingSupported()
|
||||
{
|
||||
// look for deep binding support in _env
|
||||
Object support = _env.get(DEEP_BINDING);
|
||||
if (support!=null)
|
||||
return Boolean.parseBoolean(String.valueOf(support));
|
||||
|
||||
if (_parent!=null)
|
||||
return _parent.isDeepBindingSupported();
|
||||
// probably a root context
|
||||
return Boolean.parseBoolean(System.getProperty(DEEP_BINDING,"false"));
|
||||
}
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Getter for _name
|
||||
|
@ -183,27 +192,69 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
_parser = parser;
|
||||
}
|
||||
|
||||
|
||||
public final void setEnv (Hashtable<String,Object> env)
|
||||
{
|
||||
_env.clear();
|
||||
if(env == null)
|
||||
return;
|
||||
_env.putAll(env);
|
||||
_supportDeepBinding = _env.containsKey(DEEP_BINDING);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Map<String,Binding> getBindings ()
|
||||
private Object dereference(Object ctx, String firstComponent) throws NamingException
|
||||
{
|
||||
return _bindings;
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
try
|
||||
{
|
||||
return NamingManager.getObjectInstance(ctx, _parser.parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public void setBindings(Map<String,Binding> bindings)
|
||||
private Context getContext(Name cname) throws NamingException
|
||||
{
|
||||
_bindings = bindings;
|
||||
String firstComponent = cname.get(0);
|
||||
|
||||
if (firstComponent.equals(""))
|
||||
return this;
|
||||
|
||||
Binding binding = getBinding (firstComponent);
|
||||
if (binding == null)
|
||||
{
|
||||
NameNotFoundException nnfe = new NameNotFoundException(firstComponent + " is not bound");
|
||||
nnfe.setRemainingName(cname);
|
||||
throw nnfe;
|
||||
}
|
||||
|
||||
Object ctx = dereference(binding.getObject(), firstComponent);
|
||||
|
||||
if (!(ctx instanceof Context))
|
||||
throw new NotContextException(firstComponent + " not a context in " + this.getNameInNamespace());
|
||||
|
||||
return (Context)ctx;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Bind a name to an object
|
||||
|
@ -244,7 +295,8 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
}
|
||||
else
|
||||
{
|
||||
if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0));
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0));
|
||||
|
||||
//walk down the subcontext hierarchy
|
||||
//need to ignore trailing empty "" name components
|
||||
|
@ -256,13 +308,13 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
ctx = this;
|
||||
else
|
||||
{
|
||||
|
||||
Binding binding = getBinding (firstComponent);
|
||||
if (binding == null) {
|
||||
if (_supportDeepBinding)
|
||||
if (binding == null)
|
||||
{
|
||||
if (isDeepBindingSupported())
|
||||
{
|
||||
Name subname = _parser.parse(firstComponent);
|
||||
Context subctx = new NamingContext((Hashtable)_env.clone(),firstComponent,this,_parser);
|
||||
Context subctx = new NamingContext(_env,firstComponent,this,_parser, null);
|
||||
addBinding(subname,subctx);
|
||||
binding = getBinding(subname);
|
||||
}
|
||||
|
@ -272,28 +324,9 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
}
|
||||
}
|
||||
|
||||
ctx = binding.getObject();
|
||||
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
try
|
||||
{
|
||||
ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
ctx = dereference(binding.getObject(),firstComponent);
|
||||
}
|
||||
|
||||
|
||||
if (ctx instanceof Context)
|
||||
{
|
||||
((Context)ctx).bind (cname.getSuffix(1), obj);
|
||||
|
@ -354,57 +387,14 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
if (binding != null)
|
||||
throw new NameAlreadyBoundException (cname.toString());
|
||||
|
||||
Context ctx = new NamingContext ((Hashtable)_env.clone(), cname.get(0), this, _parser);
|
||||
Context ctx = new NamingContext (_env, cname.get(0), this, _parser);
|
||||
addBinding (cname, ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
//If the name has multiple subcontexts, walk the hierarchy by
|
||||
//fetching the first one. All intermediate subcontexts in the
|
||||
//name must already exist.
|
||||
String firstComponent = cname.get(0);
|
||||
Object ctx = null;
|
||||
|
||||
if (firstComponent.equals(""))
|
||||
ctx = this;
|
||||
else
|
||||
{
|
||||
Binding binding = getBinding (firstComponent);
|
||||
if (binding == null)
|
||||
throw new NameNotFoundException (firstComponent + " is not bound");
|
||||
|
||||
ctx = binding.getObject();
|
||||
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
if(__log.isDebugEnabled())__log.debug("Object bound at "+firstComponent +" is a Reference");
|
||||
try
|
||||
{
|
||||
ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx instanceof Context)
|
||||
{
|
||||
return ((Context)ctx).createSubcontext (cname.getSuffix(1));
|
||||
}
|
||||
else
|
||||
throw new NotContextException (firstComponent +" is not a Context");
|
||||
return getContext(cname).createSubcontext (cname.getSuffix(1));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Create a Context as a child of this one
|
||||
|
@ -420,8 +410,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
return createSubcontext(_parser.parse(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
|
@ -436,8 +424,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
removeBinding(_parser.parse(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
|
@ -463,19 +449,17 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
public Object lookup(Name name)
|
||||
throws NamingException
|
||||
{
|
||||
if(__log.isDebugEnabled())__log.debug("Looking up name=\""+name+"\"");
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Looking up name=\""+name+"\"");
|
||||
Name cname = toCanonicalName(name);
|
||||
|
||||
if ((cname == null) || (cname.size() == 0))
|
||||
{
|
||||
__log.debug("Null or empty name, returning copy of this context");
|
||||
NamingContext ctx = new NamingContext (_env, _name, _parent, _parser);
|
||||
ctx._bindings=_bindings;
|
||||
return ctx;
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Null or empty name, returning shallowCopy of this context");
|
||||
return shallowCopy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (cname.size() == 1)
|
||||
{
|
||||
Binding binding = getBinding (cname);
|
||||
|
@ -486,7 +470,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
throw nnfe;
|
||||
}
|
||||
|
||||
|
||||
Object o = binding.getObject();
|
||||
|
||||
//handle links by looking up the link
|
||||
|
@ -505,7 +488,7 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
}
|
||||
else if (o instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
// TODO use deference ??
|
||||
try
|
||||
{
|
||||
return NamingManager.getObjectInstance(o, cname, this, _env);
|
||||
|
@ -516,7 +499,7 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
LOG.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -524,54 +507,9 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
return o;
|
||||
}
|
||||
|
||||
//it is a multipart name, recurse to the first subcontext
|
||||
|
||||
String firstComponent = cname.get(0);
|
||||
Object ctx = null;
|
||||
|
||||
if (firstComponent.equals(""))
|
||||
ctx = this;
|
||||
else
|
||||
{
|
||||
|
||||
Binding binding = getBinding (firstComponent);
|
||||
if (binding == null)
|
||||
{
|
||||
NameNotFoundException nnfe = new NameNotFoundException();
|
||||
nnfe.setRemainingName(cname);
|
||||
throw nnfe;
|
||||
}
|
||||
|
||||
//as we have bound a reference to an object factory
|
||||
//for the component specific contexts
|
||||
//at "comp" we need to resolve the reference
|
||||
ctx = binding.getObject();
|
||||
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
try
|
||||
{
|
||||
ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(ctx instanceof Context))
|
||||
throw new NotContextException();
|
||||
|
||||
return ((Context)ctx).lookup (cname.getSuffix(1));
|
||||
return getContext(cname).lookup (cname.getSuffix(1));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Lookup binding of an object by name
|
||||
|
@ -587,8 +525,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
return lookup (_parser.parse(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Lookup link bound to name
|
||||
|
@ -603,12 +539,11 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
{
|
||||
Name cname = toCanonicalName(name);
|
||||
|
||||
if (cname == null)
|
||||
if (cname == null || name.isEmpty())
|
||||
{
|
||||
NamingContext ctx = new NamingContext (_env, _name, _parent, _parser);
|
||||
ctx._bindings=_bindings;
|
||||
return ctx;
|
||||
return shallowCopy();
|
||||
}
|
||||
|
||||
if (cname.size() == 0)
|
||||
throw new NamingException ("Name is empty");
|
||||
|
||||
|
@ -618,75 +553,12 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
if (binding == null)
|
||||
throw new NameNotFoundException();
|
||||
|
||||
Object o = binding.getObject();
|
||||
|
||||
//handle links by looking up the link
|
||||
if (o instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
try
|
||||
{
|
||||
return NamingManager.getObjectInstance(o, cname.getPrefix(1), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//object is either a LinkRef which we don't dereference
|
||||
//or a plain object in which case spec says we return it
|
||||
return o;
|
||||
}
|
||||
return dereference(binding.getObject(), cname.getPrefix(1).toString());
|
||||
}
|
||||
|
||||
|
||||
//it is a multipart name, recurse to the first subcontext
|
||||
String firstComponent = cname.get(0);
|
||||
Object ctx = null;
|
||||
|
||||
if (firstComponent.equals(""))
|
||||
ctx = this;
|
||||
else
|
||||
{
|
||||
Binding binding = getBinding (firstComponent);
|
||||
if (binding == null)
|
||||
throw new NameNotFoundException ();
|
||||
|
||||
ctx = binding.getObject();
|
||||
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
try
|
||||
{
|
||||
ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ctx instanceof Context))
|
||||
throw new NotContextException();
|
||||
|
||||
return ((Context)ctx).lookup (cname.getSuffix(1));
|
||||
return getContext(cname).lookup (cname.getSuffix(1));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Lookup link bound to name
|
||||
|
@ -702,7 +574,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
return lookupLink (_parser.parse(name));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* List all names bound at Context named by Name
|
||||
|
@ -715,65 +586,24 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
public NamingEnumeration list(Name name)
|
||||
throws NamingException
|
||||
{
|
||||
if(__log.isDebugEnabled())__log.debug("list() on Context="+getName()+" for name="+name);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("list() on Context="+getName()+" for name="+name);
|
||||
Name cname = toCanonicalName(name);
|
||||
|
||||
|
||||
|
||||
if (cname == null)
|
||||
{
|
||||
return new NameEnumeration(__empty.iterator());
|
||||
}
|
||||
|
||||
|
||||
if (cname.size() == 0)
|
||||
{
|
||||
return new NameEnumeration (_bindings.values().iterator());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//multipart name
|
||||
String firstComponent = cname.get(0);
|
||||
Object ctx = null;
|
||||
|
||||
if (firstComponent.equals(""))
|
||||
ctx = this;
|
||||
else
|
||||
{
|
||||
Binding binding = getBinding (firstComponent);
|
||||
if (binding == null)
|
||||
throw new NameNotFoundException ();
|
||||
|
||||
ctx = binding.getObject();
|
||||
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
if(__log.isDebugEnabled())__log.debug("Dereferencing Reference for "+name.get(0));
|
||||
try
|
||||
{
|
||||
ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ctx instanceof Context))
|
||||
throw new NotContextException();
|
||||
|
||||
return ((Context)ctx).list (cname.getSuffix(1));
|
||||
return getContext(cname).list (cname.getSuffix(1));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* List all names bound at Context named by Name
|
||||
|
@ -789,8 +619,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
return list(_parser.parse(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* List all Bindings present at Context named by Name
|
||||
|
@ -815,48 +643,7 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
return new BindingEnumeration (_bindings.values().iterator());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//multipart name
|
||||
String firstComponent = cname.get(0);
|
||||
Object ctx = null;
|
||||
|
||||
//if a name has a leading "/" it is parsed as "" so ignore it by staying
|
||||
//at this level in the tree
|
||||
if (firstComponent.equals(""))
|
||||
ctx = this;
|
||||
else
|
||||
{
|
||||
//it is a non-empty name component
|
||||
Binding binding = getBinding (firstComponent);
|
||||
if (binding == null)
|
||||
throw new NameNotFoundException ();
|
||||
|
||||
ctx = binding.getObject();
|
||||
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
try
|
||||
{
|
||||
ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ctx instanceof Context))
|
||||
throw new NotContextException();
|
||||
|
||||
return ((Context)ctx).listBindings (cname.getSuffix(1));
|
||||
return getContext(cname).listBindings (cname.getSuffix(1));
|
||||
}
|
||||
|
||||
|
||||
|
@ -917,49 +704,7 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
}
|
||||
else
|
||||
{
|
||||
//walk down the subcontext hierarchy
|
||||
if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0));
|
||||
|
||||
String firstComponent = cname.get(0);
|
||||
Object ctx = null;
|
||||
|
||||
|
||||
if (firstComponent.equals(""))
|
||||
ctx = this;
|
||||
else
|
||||
{
|
||||
Binding binding = getBinding (name.get(0));
|
||||
if (binding == null)
|
||||
throw new NameNotFoundException (name.get(0)+ " is not bound");
|
||||
|
||||
ctx = binding.getObject();
|
||||
|
||||
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
try
|
||||
{
|
||||
ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx instanceof Context)
|
||||
{
|
||||
((Context)ctx).rebind (cname.getSuffix(1), obj);
|
||||
}
|
||||
else
|
||||
throw new NotContextException ("Object bound at "+firstComponent +" is not a Context");
|
||||
getContext(cname).rebind (cname.getSuffix(1), obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1020,7 +765,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
if (cname.size() == 0)
|
||||
throw new NamingException ("Name is empty");
|
||||
|
||||
|
||||
//if no subcontexts, just unbind it
|
||||
if (cname.size() == 1)
|
||||
{
|
||||
|
@ -1028,48 +772,7 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
}
|
||||
else
|
||||
{
|
||||
//walk down the subcontext hierarchy
|
||||
if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0));
|
||||
|
||||
String firstComponent = cname.get(0);
|
||||
Object ctx = null;
|
||||
|
||||
|
||||
if (firstComponent.equals(""))
|
||||
ctx = this;
|
||||
else
|
||||
{
|
||||
Binding binding = getBinding (name.get(0));
|
||||
if (binding == null)
|
||||
throw new NameNotFoundException (name.get(0)+ " is not bound");
|
||||
|
||||
ctx = binding.getObject();
|
||||
|
||||
if (ctx instanceof Reference)
|
||||
{
|
||||
//deference the object
|
||||
try
|
||||
{
|
||||
ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env);
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn("",e);
|
||||
throw new NamingException (e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx instanceof Context)
|
||||
{
|
||||
((Context)ctx).unbind (cname.getSuffix(1));
|
||||
}
|
||||
else
|
||||
throw new NotContextException ("Object bound at "+firstComponent +" is not a Context");
|
||||
getContext(cname).unbind (cname.getSuffix(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1198,7 +901,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
return _parser;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Get the full name of this Context node
|
||||
|
@ -1227,7 +929,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
return name.toString();
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Add an environment setting to this Context
|
||||
|
@ -1242,13 +943,25 @@ public class NamingContext implements Context, Cloneable, 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.
|
||||
|
@ -1277,7 +990,7 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
@Override
|
||||
public Hashtable getEnvironment ()
|
||||
{
|
||||
return (Hashtable)_env.clone();
|
||||
return _env;
|
||||
}
|
||||
|
||||
/*------------------------------------------------*/
|
||||
|
@ -1302,13 +1015,15 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
break;
|
||||
}
|
||||
|
||||
if(__log.isDebugEnabled())
|
||||
__log.debug("Adding binding with key="+key+" obj="+obj+" for context="+_name+" as "+binding);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Adding binding with key="+key+" obj="+obj+" for context="+_name+" as "+binding);
|
||||
|
||||
if (binding!=null)
|
||||
{
|
||||
if (_bindings.containsKey(key)) {
|
||||
if(_supportDeepBinding) {
|
||||
if (_bindings.putIfAbsent(key, binding)!=null)
|
||||
{
|
||||
if(isDeepBindingSupported())
|
||||
{
|
||||
// quietly return (no exception)
|
||||
// this is jndi spec breaking, but is added to support broken
|
||||
// jndi users like openejb.
|
||||
|
@ -1316,7 +1031,6 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
}
|
||||
throw new NameAlreadyBoundException(name.toString());
|
||||
}
|
||||
_bindings.put(key,binding);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1329,10 +1043,9 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
*/
|
||||
public Binding getBinding (Name name)
|
||||
{
|
||||
return (Binding) _bindings.get(name.toString());
|
||||
return _bindings.get(name.toString());
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/**
|
||||
* Get a name to object binding from this Context
|
||||
|
@ -1342,15 +1055,15 @@ public class NamingContext implements Context, Cloneable, Dumpable
|
|||
*/
|
||||
public Binding getBinding (String name)
|
||||
{
|
||||
return (Binding) _bindings.get(name);
|
||||
return _bindings.get(name);
|
||||
}
|
||||
|
||||
/*------------------------------------------------*/
|
||||
public void removeBinding (Name name)
|
||||
{
|
||||
String key = name.toString();
|
||||
if (__log.isDebugEnabled())
|
||||
__log.debug("Removing binding with key="+key);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Removing binding with key="+key);
|
||||
Binding binding = _bindings.remove(key);
|
||||
if (binding!=null)
|
||||
{
|
||||
|
@ -1390,65 +1103,21 @@ public class NamingContext implements Context, Cloneable, 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()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
try
|
||||
{
|
||||
dump(buf,"");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
__log.warn(e);
|
||||
}
|
||||
return buf.toString();
|
||||
return Dumpable.dump(this);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void dump(Appendable out,String indent) throws IOException
|
||||
{
|
||||
out.append(this.getClass().getSimpleName()).append("@").append(Long.toHexString(this.hashCode())).append("\n");
|
||||
int size=_bindings.size();
|
||||
int i=0;
|
||||
for (Map.Entry<String,Binding> entry : ((Map<String,Binding>)_bindings).entrySet())
|
||||
{
|
||||
boolean last=++i==size;
|
||||
out.append(indent).append(" +- ").append(entry.getKey()).append(": ");
|
||||
|
||||
Binding binding = entry.getValue();
|
||||
Object value = binding.getObject();
|
||||
|
||||
if ("comp".equals(entry.getKey()) && value instanceof Reference && "org.eclipse.jetty.jndi.ContextFactory".equals(((Reference)value).getFactoryClassName()))
|
||||
{
|
||||
ContextFactory.dump(out,indent+(last?" ":" | "));
|
||||
}
|
||||
else if (value instanceof Dumpable)
|
||||
{
|
||||
((Dumpable)value).dump(out,indent+(last?" ":" | "));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.append(value.getClass().getSimpleName()).append("=");
|
||||
out.append(String.valueOf(value).replace('\n','|').replace('\r','|'));
|
||||
out.append("\n");
|
||||
}
|
||||
}
|
||||
Dumpable.dumpObjects(out,indent,this, _bindings);
|
||||
}
|
||||
|
||||
private Collection<Listener> findListeners()
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.eclipse.jetty.jndi;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
|
@ -29,6 +28,7 @@ import javax.naming.NameParser;
|
|||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*/
|
||||
public class NamingUtil
|
||||
{
|
||||
public final static Logger __log=org.eclipse.jetty.util.log.Log.getLogger("jndi");
|
||||
private static final Logger LOG = Log.getLogger(NamingUtil.class);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -67,20 +67,20 @@ public class NamingUtil
|
|||
try
|
||||
{
|
||||
subCtx = (Context)subCtx.lookup (name.get(i));
|
||||
if(__log.isDebugEnabled())
|
||||
__log.debug("Subcontext "+name.get(i)+" already exists");
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Subcontext "+name.get(i)+" already exists");
|
||||
}
|
||||
catch (NameNotFoundException e)
|
||||
{
|
||||
subCtx = subCtx.createSubcontext(name.get(i));
|
||||
if(__log.isDebugEnabled())
|
||||
__log.debug("Subcontext "+name.get(i)+" created");
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Subcontext "+name.get(i)+" created");
|
||||
}
|
||||
}
|
||||
|
||||
subCtx.rebind (name.get(name.size() - 1), obj);
|
||||
if(__log.isDebugEnabled())
|
||||
__log.debug("Bound object to "+name.get(name.size() - 1));
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Bound object to "+name.get(name.size() - 1));
|
||||
return subCtx;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.jndi.java;
|
||||
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NameParser;
|
||||
|
@ -31,7 +29,7 @@ import javax.naming.StringRefAddr;
|
|||
|
||||
import org.eclipse.jetty.jndi.ContextFactory;
|
||||
import org.eclipse.jetty.jndi.NamingContext;
|
||||
import org.eclipse.jetty.jndi.NamingUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
|
@ -46,7 +44,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*/
|
||||
public class javaRootURLContext implements Context
|
||||
{
|
||||
private static Logger __log = NamingUtil.__log;
|
||||
private static final Logger LOG = Log.getLogger(javaRootURLContext.class);
|
||||
|
||||
public static final String URL_PREFIX = "java:";
|
||||
|
||||
|
@ -76,7 +74,7 @@ public class javaRootURLContext implements Context
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
__log.warn(e);
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,7 +317,8 @@ public class javaRootURLContext implements Context
|
|||
{
|
||||
String head = name.get(0);
|
||||
|
||||
if(__log.isDebugEnabled())__log.debug("Head element of name is: "+head);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Head element of name is: "+head);
|
||||
|
||||
if (head.startsWith(URL_PREFIX))
|
||||
{
|
||||
|
@ -328,7 +327,8 @@ public class javaRootURLContext implements Context
|
|||
if (head.length() > 0)
|
||||
name.add(0, head);
|
||||
|
||||
if(__log.isDebugEnabled())__log.debug("name modified to "+name.toString());
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("name modified to "+name.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,7 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.jndi.java;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
@ -49,6 +51,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
|
|||
import org.eclipse.jetty.server.handler.HandlerList;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
/**
|
||||
*
|
||||
|
@ -288,7 +291,7 @@ public class TestJNDI
|
|||
ClassLoader currentLoader = currentThread.getContextClassLoader();
|
||||
ClassLoader childLoader1 = new URLClassLoader(new URL[0], currentLoader);
|
||||
ClassLoader childLoader2 = new URLClassLoader(new URL[0], currentLoader);
|
||||
|
||||
InitialContext initCtx = null;
|
||||
try
|
||||
{
|
||||
|
||||
|
@ -325,7 +328,7 @@ public class TestJNDI
|
|||
|
||||
//Set up the tccl before doing any jndi operations
|
||||
currentThread.setContextClassLoader(childLoader1);
|
||||
InitialContext initCtx = new InitialContext();
|
||||
initCtx = new InitialContext();
|
||||
|
||||
//Test we can lookup the root java: naming tree
|
||||
Context sub0 = (Context)initCtx.lookup("java:");
|
||||
|
@ -439,30 +442,66 @@ public class TestJNDI
|
|||
|
||||
//check locking the context
|
||||
Context ectx = (Context)initCtx.lookup("java:comp");
|
||||
//make a deep structure lie ttt/ttt2 for later use
|
||||
Context ttt = ectx.createSubcontext("ttt");
|
||||
ttt.createSubcontext("ttt2");
|
||||
//bind a value
|
||||
ectx.bind("crud", "xxx");
|
||||
ectx.addToEnvironment("org.eclipse.jndi.immutable", "TRUE");
|
||||
//lock
|
||||
ectx.addToEnvironment("org.eclipse.jetty.jndi.lock", "TRUE");
|
||||
//check we can't get the lock
|
||||
assertFalse(ectx.getEnvironment().containsKey("org.eclipse.jetty.jndi.lock"));
|
||||
//check once locked we can still do lookups
|
||||
assertEquals ("xxx", initCtx.lookup("java:comp/crud"));
|
||||
assertNotNull(initCtx.lookup("java:comp/ttt/ttt2"));
|
||||
|
||||
//test trying to bind into java:comp after lock
|
||||
InitialContext zzz = null;
|
||||
try
|
||||
{
|
||||
ectx.bind("crud2", "xxx2");
|
||||
zzz = new InitialContext();
|
||||
|
||||
((Context)zzz.lookup("java:comp")).bind("crud2", "xxx2");
|
||||
fail("Should not be able to write to locked context");
|
||||
|
||||
}
|
||||
catch (NamingException ne)
|
||||
{
|
||||
//expected failure to modify immutable context
|
||||
assertThat(ne.getMessage(), Matchers.containsString("immutable"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
zzz.close();
|
||||
}
|
||||
|
||||
|
||||
initCtx.close();
|
||||
//test trying to bind into a deep structure inside java:comp after lock
|
||||
try
|
||||
{
|
||||
zzz = new InitialContext();
|
||||
|
||||
((Context)zzz.lookup("java:comp/ttt/ttt2")).bind("zzz2", "zzz2");
|
||||
fail("Should not be able to write to locked context");
|
||||
}
|
||||
catch (NamingException ne)
|
||||
{
|
||||
assertThat(ne.getMessage(), Matchers.containsString("immutable"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
zzz.close();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
//make some effort to clean up
|
||||
initCtx.close();
|
||||
InitialContext ic = new InitialContext();
|
||||
Context java = (Context)ic.lookup("java:");
|
||||
java.destroySubcontext("zero");
|
||||
java.destroySubcontext("fee");
|
||||
currentThread.setContextClassLoader(childLoader1);
|
||||
Context comp = (Context)ic.lookup("java:comp");
|
||||
comp.addToEnvironment("org.eclipse.jetty.jndi.unlock", "TRUE");
|
||||
comp.destroySubcontext("env");
|
||||
comp.unbind("crud");
|
||||
comp.unbind("crud2");
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.naming.NameParser;
|
|||
import javax.naming.NamingException;
|
||||
|
||||
import org.eclipse.jetty.jndi.NamingUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
|
@ -41,7 +42,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*/
|
||||
public abstract class NamingEntry
|
||||
{
|
||||
private static Logger __log = NamingUtil.__log;
|
||||
private static final Logger LOG = Log.getLogger(NamingEntry.class);
|
||||
public static final String __contextName = "__"; //all NamingEntries stored in context called "__"
|
||||
protected final Object _scope;
|
||||
protected final String _jndiName; //the name representing the object associated with the NamingEntry
|
||||
|
@ -104,7 +105,8 @@ public abstract class NamingEntry
|
|||
// TODO - check on the whole overriding/non-overriding thing
|
||||
InitialContext ic = new InitialContext();
|
||||
Context env = (Context)ic.lookup("java:comp/env");
|
||||
__log.debug("Binding java:comp/env/"+localName+" to "+_objectNameString);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Binding java:comp/env/"+localName+" to "+_objectNameString);
|
||||
NamingUtil.bind(env, localName, new LinkRef(_objectNameString));
|
||||
}
|
||||
|
||||
|
@ -117,12 +119,13 @@ public abstract class NamingEntry
|
|||
{
|
||||
InitialContext ic = new InitialContext();
|
||||
Context env = (Context)ic.lookup("java:comp/env");
|
||||
__log.debug("Unbinding java:comp/env/"+getJndiName());
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Unbinding java:comp/env/"+getJndiName());
|
||||
env.unbind(getJndiName());
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
__log.warn(e);
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +144,7 @@ public abstract class NamingEntry
|
|||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
__log.warn(e);
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,7 +194,8 @@ public abstract class NamingEntry
|
|||
protected void save (Object object)
|
||||
throws NamingException
|
||||
{
|
||||
__log.debug("SAVE {} in {}",this,_scope);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("SAVE {} in {}",this,_scope);
|
||||
InitialContext ic = new InitialContext();
|
||||
NameParser parser = ic.getNameParser("");
|
||||
Name prefix = NamingEntryUtil.getNameForScope(_scope);
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.plus.jndi;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
|
@ -31,13 +30,13 @@ import javax.naming.NameParser;
|
|||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.eclipse.jetty.jndi.NamingUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
||||
public class NamingEntryUtil
|
||||
{
|
||||
private static Logger __log = NamingUtil.__log;
|
||||
private static final Logger LOG = Log.getLogger(NamingEntryUtil.class);
|
||||
|
||||
/**
|
||||
* Link a name in a webapp's java:/comp/evn namespace to a pre-existing
|
||||
|
@ -176,7 +175,7 @@ public class NamingEntryUtil
|
|||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
__log.warn(e);
|
||||
LOG.warn(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -227,7 +226,8 @@ public class NamingEntryUtil
|
|||
}
|
||||
catch (NameNotFoundException e)
|
||||
{
|
||||
__log.debug("No entries of type "+clazz.getName()+" in context="+context);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("No entries of type "+clazz.getName()+" in context="+context);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.naming.NamingException;
|
|||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.eclipse.jetty.jndi.NamingUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
|
@ -35,7 +36,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*/
|
||||
public class Transaction extends NamingEntry
|
||||
{
|
||||
private static Logger __log = NamingUtil.__log;
|
||||
private static final Logger LOG = Log.getLogger(Transaction.class);
|
||||
public static final String USER_TRANSACTION = "UserTransaction";
|
||||
|
||||
|
||||
|
@ -74,7 +75,8 @@ public class Transaction extends NamingEntry
|
|||
{
|
||||
InitialContext ic = new InitialContext();
|
||||
Context env = (Context)ic.lookup("java:comp/env");
|
||||
__log.debug("Binding java:comp/env"+getJndiName()+" to "+_objectNameString);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Binding java:comp/env"+getJndiName()+" to "+_objectNameString);
|
||||
NamingUtil.bind(env, localName, new LinkRef(_objectNameString));
|
||||
}
|
||||
|
||||
|
@ -88,7 +90,8 @@ public class Transaction extends NamingEntry
|
|||
//ignore the name, it is always bound to java:comp
|
||||
InitialContext ic = new InitialContext();
|
||||
Context env = (Context)ic.lookup("java:comp");
|
||||
__log.debug("Binding java:comp/"+getJndiName()+" to "+_objectNameString);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Binding java:comp/"+getJndiName()+" to "+_objectNameString);
|
||||
NamingUtil.bind(env, getJndiName(), new LinkRef(_objectNameString));
|
||||
}
|
||||
|
||||
|
@ -102,12 +105,13 @@ public class Transaction extends NamingEntry
|
|||
{
|
||||
InitialContext ic = new InitialContext();
|
||||
Context env = (Context)ic.lookup("java:comp");
|
||||
__log.debug("Unbinding java:comp/"+getJndiName());
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Unbinding java:comp/"+getJndiName());
|
||||
env.unbind(getJndiName());
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
__log.warn(e);
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ 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;
|
||||
|
@ -118,7 +119,7 @@ public class PlusConfiguration extends AbstractConfiguration
|
|||
_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
|
||||
{
|
||||
|
|
|
@ -23,5 +23,6 @@ Log4j is released under the Apache 2.0 license.
|
|||
http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
[ini]
|
||||
log4j2.version?=2.11.1
|
||||
log4j2.version?=2.11.2
|
||||
disruptor.version=3.4.2
|
||||
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/log4j2/
|
||||
|
|
|
@ -19,6 +19,7 @@ log4j2-impl
|
|||
|
||||
[files]
|
||||
maven://org.apache.logging.log4j/log4j-core/${log4j2.version}|lib/log4j2/log4j-core-${log4j2.version}.jar
|
||||
maven://com.lmax/disruptor/${disruptor.version}|lib/log4j2/disruptor-${disruptor.version}.jar
|
||||
basehome:modules/log4j2-impl
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="warn" name="Jetty" >
|
||||
|
||||
<Appenders>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="error">
|
||||
<AppenderRef ref="STDOUT"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
<properties>
|
||||
<property name="logging.dir">${sys:jetty.logging.dir:-logs}</property>
|
||||
</properties>
|
||||
|
||||
<Appenders>
|
||||
<Console name="console" target="SYSTEM_ERR">
|
||||
|
@ -16,24 +12,33 @@
|
|||
</PatternLayout>
|
||||
</Console>
|
||||
|
||||
<!--
|
||||
<RollingFile name="file"
|
||||
fileName="${jetty.logging.dir}/jetty.log"
|
||||
filePattern="${jetty.logging.dir}/jetty-%d{MM-dd-yyyy}.log.gz"
|
||||
|
||||
<RollingRandomAccessFile name="file"
|
||||
fileName="${logging.dir}/jetty.log"
|
||||
filePattern="${logging.dir}/jetty-%d{MM-dd-yyyy}.log.gz"
|
||||
ignoreExceptions="false">
|
||||
<PatternLayout>
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n</Pattern>
|
||||
<Pattern>%d [%t] %-5p %c %x - %m%n</Pattern>
|
||||
</PatternLayout>
|
||||
<SizeBasedTriggeringPolicy size="10MB"/>
|
||||
<DefaultRolloverStrategy max="10"/>
|
||||
</RollingFile>
|
||||
-->
|
||||
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<SizeBasedTriggeringPolicy size="10 MB"/>
|
||||
</Policies>
|
||||
</RollingRandomAccessFile>
|
||||
|
||||
</Appenders>
|
||||
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<AppenderRef ref="console"/>
|
||||
</Root>
|
||||
<!--
|
||||
To have all logger async
|
||||
<AsyncRoot level="info">
|
||||
<AppenderRef ref="file"/>
|
||||
</AsyncRoot>
|
||||
-->
|
||||
</Loggers>
|
||||
|
||||
</Configuration>
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -21,7 +21,7 @@
|
|||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<build-support.version>1.4</build-support.version>
|
||||
<slf4j.version>1.8.0-beta2</slf4j.version>
|
||||
<log4j2.version>2.11.1</log4j2.version>
|
||||
<log4j2.version>2.11.2</log4j2.version>
|
||||
<logback.version>1.3.0-alpha4</logback.version>
|
||||
<spring-version>5.1.1.RELEASE</spring-version>
|
||||
<jetty-test-policy.version>1.2</jetty-test-policy.version>
|
||||
|
@ -36,7 +36,7 @@
|
|||
<jmhjar.name>benchmarks</jmhjar.name>
|
||||
<tycho-version>1.2.0</tycho-version>
|
||||
<cbi-plugins.version>1.1.5</cbi-plugins.version>
|
||||
<junit.version>5.3.1</junit.version>
|
||||
<junit.version>5.4.0</junit.version>
|
||||
<maven.version>3.6.0</maven.version>
|
||||
<maven.resolver.version>1.3.1</maven.resolver.version>
|
||||
<weld.version>2.4.5.Final</weld.version>
|
||||
|
|
|
@ -473,7 +473,7 @@ public class DistributionTester
|
|||
@Override
|
||||
public void close()
|
||||
{
|
||||
destroy();
|
||||
stop();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.http2.client.HTTP2Client;
|
|||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets;
|
||||
import org.eclipse.jetty.unixsocket.server.UnixSocketConnector;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledOnJre;
|
||||
|
@ -265,4 +266,47 @@ public class DistributionTests extends AbstractDistributionTest
|
|||
Files.deleteIfExists(sockFile);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLog4j2ModuleWithSimpleWebAppWithJSP() throws Exception
|
||||
{
|
||||
Path jettyBase = Files.createTempDirectory( "jetty_base");
|
||||
String jettyVersion = System.getProperty("jettyVersion");
|
||||
DistributionTester distribution = DistributionTester.Builder.newInstance()
|
||||
.jettyVersion(jettyVersion)
|
||||
.jettyBase(jettyBase)
|
||||
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
|
||||
.build();
|
||||
|
||||
String[] args1 = {
|
||||
"--create-startd",
|
||||
"--approve-all-licenses",
|
||||
"--add-to-start=resources,server,http,webapp,deploy,jsp,servlet,servlets,logging-log4j2"
|
||||
};
|
||||
try (DistributionTester.Run run1 = distribution.start(args1))
|
||||
{
|
||||
assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
|
||||
assertEquals(0, run1.getExitValue());
|
||||
assertTrue(Files.exists(jettyBase.resolve("resources/log4j2.xml")));
|
||||
|
||||
File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-webapp:war:" + jettyVersion);
|
||||
distribution.installWarFile(war, "test");
|
||||
|
||||
int port = distribution.freePort();
|
||||
try (DistributionTester.Run run2 = distribution.start("jetty.http.port=" + port))
|
||||
{
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
|
||||
|
||||
startHttpClient();
|
||||
ContentResponse response = client.GET("http://localhost:" + port + "/test/index.jsp");
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
assertThat(response.getContentAsString(), containsString("Hello"));
|
||||
assertThat(response.getContentAsString(), not(containsString("<%")));
|
||||
assertTrue(Files.exists(jettyBase.resolve("resources/log4j2.xml")));
|
||||
}
|
||||
} finally
|
||||
{
|
||||
IO.delete(jettyBase.toFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue