Merged branch 'jetty-9.4.x' into 'jetty-10.0.x'.

This commit is contained in:
Simone Bordet 2019-06-06 17:58:49 +02:00
commit bf53925cfb
17 changed files with 646 additions and 1299 deletions

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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()

View File

@ -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;
}

View File

@ -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());
}
}

View File

@ -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");

View File

@ -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);

View File

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

View File

@ -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);
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -473,7 +473,7 @@ public class DistributionTester
@Override
public void close()
{
destroy();
stop();
}
/**

View File

@ -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());
}
}
}