Jetty 9.4.x 3755 annotation/jndi example cleanup (#3763)
* Issue #3755 Annotation example cleanup + Created JettyDistribution class as common utility to locate a jetty distribution for examples. + Fixed ServerWithAnnotations to correctly use the test-spec-webapp + Added AttributeContainerMap as a better way to treat attribute values as beans. This avoids them appearing twice in a dump and always associates them with their key. + Added NamingDump and use it in EnvConfiguration and jetty-plus.xml so that a server dump will contain dumps of the server local tree and each contexts java:comp/env tree + Improved the dump format of NamingContext and WebAppContext + Improved the toString format of several associated classes Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
275f83c1d0
commit
862e6d008e
|
@ -0,0 +1,109 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.embedded;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* A utility test class to locate a Jetty Distribution for testing purposes by searching:
|
||||
* <ul>
|
||||
* <li>The <code>jetty.home</code> system property</li>
|
||||
* <li>The <code>JETTY_HOME</code> environment variable</li>
|
||||
* <li>The working directory hierarchy with subdirectory <code>jetty-distribution/target/home</code></li>
|
||||
* </ul>
|
||||
*/
|
||||
public class JettyDistribution
|
||||
{
|
||||
private final static Logger LOG = Log.getLogger(JettyDistribution.class);
|
||||
public final static Path DISTRIBUTION;
|
||||
|
||||
static
|
||||
{
|
||||
Path distro = asJettyDistribution(System.getProperty("jetty.home"));
|
||||
if (distro==null)
|
||||
distro = asJettyDistribution(System.getenv().get("JETTY_HOME"));
|
||||
|
||||
if (distro==null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Path working = new File(".").getAbsoluteFile().getCanonicalFile().toPath();
|
||||
while(distro == null && working !=null )
|
||||
{
|
||||
distro = asJettyDistribution(working.resolve("jetty-distribution/target/distribution").toString());
|
||||
working = working.getParent();
|
||||
}
|
||||
}
|
||||
catch(Throwable th)
|
||||
{
|
||||
LOG.warn(th);
|
||||
}
|
||||
}
|
||||
DISTRIBUTION = distro;
|
||||
}
|
||||
|
||||
private static Path asJettyDistribution(String test)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (StringUtil.isBlank(test))
|
||||
{
|
||||
LOG.info("asJettyDistribution {} is blank", test);
|
||||
return null;
|
||||
}
|
||||
|
||||
File dir = new File(test);
|
||||
if (!dir.exists() || !dir.isDirectory())
|
||||
{
|
||||
LOG.info("asJettyDistribution {} is not a directory", test);
|
||||
return null;
|
||||
}
|
||||
|
||||
File demoBase = new File(dir,"demo-base");
|
||||
if (!demoBase.exists() || !demoBase.isDirectory())
|
||||
{
|
||||
LOG.info("asJettyDistribution {} has no demo-base", test);
|
||||
return null;
|
||||
}
|
||||
|
||||
LOG.info("asJettyDistribution {}", dir);
|
||||
return dir.getAbsoluteFile().getCanonicalFile().toPath();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.ignore(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Path resolve(String path)
|
||||
{
|
||||
return DISTRIBUTION.resolve(path);
|
||||
}
|
||||
|
||||
public static void main(String... arg)
|
||||
{
|
||||
System.err.println("Jetty Distribution is " + DISTRIBUTION);
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
package org.eclipse.jetty.embedded;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||
|
@ -60,27 +59,14 @@ public class LikeJettyXml
|
|||
public static void main( String[] args ) throws Exception
|
||||
{
|
||||
// Path to as-built jetty-distribution directory
|
||||
String jettyHomeBuild = "jetty-distribution/target/distribution";
|
||||
|
||||
String jettyHomeBuild = JettyDistribution.DISTRIBUTION.toString();
|
||||
|
||||
// Find jetty home and base directories
|
||||
String homePath = System.getProperty("jetty.home", jettyHomeBuild);
|
||||
File start_jar = new File(homePath,"start.jar");
|
||||
if (!start_jar.exists())
|
||||
{
|
||||
homePath = jettyHomeBuild = "jetty-distribution/target/distribution";
|
||||
start_jar = new File(homePath,"start.jar");
|
||||
if (!start_jar.exists())
|
||||
throw new FileNotFoundException(start_jar.toString());
|
||||
}
|
||||
|
||||
File homeDir = new File(homePath);
|
||||
|
||||
String basePath = System.getProperty("jetty.base", homeDir + "/demo-base");
|
||||
File baseDir = new File(basePath);
|
||||
if(!baseDir.exists())
|
||||
{
|
||||
throw new FileNotFoundException(baseDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
// Configure jetty.home and jetty.base system properties
|
||||
String jetty_home = homeDir.getAbsolutePath();
|
||||
|
@ -88,7 +74,6 @@ public class LikeJettyXml
|
|||
System.setProperty("jetty.home", jetty_home);
|
||||
System.setProperty("jetty.base", jetty_base);
|
||||
|
||||
|
||||
// === jetty.xml ===
|
||||
// Setup Threadpool
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||
|
@ -219,7 +204,6 @@ public class LikeJettyXml
|
|||
lowResourcesMonitor.setPeriod(1000);
|
||||
lowResourcesMonitor.setLowResourcesIdleTimeout(200);
|
||||
lowResourcesMonitor.setMonitorThreads(true);
|
||||
lowResourcesMonitor.setMaxConnections(0);
|
||||
lowResourcesMonitor.setMaxMemory(0);
|
||||
lowResourcesMonitor.setMaxLowResourcesTime(5000);
|
||||
server.addBean(lowResourcesMonitor);
|
||||
|
|
|
@ -49,8 +49,7 @@ public class OneWebApp
|
|||
// PlusConfiguration) to choosing where the webapp will unpack itself.
|
||||
WebAppContext webapp = new WebAppContext();
|
||||
webapp.setContextPath("/");
|
||||
File warFile = new File(
|
||||
"../../tests/test-jmx/jmx-webapp/target/jmx-webapp");
|
||||
File warFile = JettyDistribution.resolve("demo-base/webapps/async-rest.war").toFile();
|
||||
webapp.setWar(warFile.getAbsolutePath());
|
||||
|
||||
// A WebAppContext is a ContextHandler as well so it needs to be set to
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.embedded;
|
|||
import java.io.File;
|
||||
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.plus.jndi.NamingDump;
|
||||
import org.eclipse.jetty.plus.jndi.Resource;
|
||||
import org.eclipse.jetty.plus.jndi.Transaction;
|
||||
import org.eclipse.jetty.security.HashLoginService;
|
||||
|
@ -47,16 +48,14 @@ public class ServerWithAnnotations
|
|||
classlist.addBefore(
|
||||
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
|
||||
"org.eclipse.jetty.annotations.AnnotationConfiguration");
|
||||
|
||||
// Create a WebApp
|
||||
WebAppContext webapp = new WebAppContext();
|
||||
webapp.setContextPath("/");
|
||||
File warFile = new File(
|
||||
"jetty-distribution/target/distribution/demo-base/webapps/test.war");
|
||||
File warFile = JettyDistribution.resolve("demo-base/webapps/test-spec.war").toFile();
|
||||
webapp.setWar(warFile.getAbsolutePath());
|
||||
webapp.setAttribute(
|
||||
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
|
||||
".*/javax.servlet-[^/]*\\.jar$|.*/servlet-api-[^/]*\\.jar$");
|
||||
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
|
||||
".*/javax.servlet-[^/]*\\.jar$|.*/servlet-api-[^/]*\\.jar$");
|
||||
server.setHandler(webapp);
|
||||
|
||||
// Register new transaction manager in JNDI
|
||||
|
@ -64,10 +63,14 @@ public class ServerWithAnnotations
|
|||
new Transaction(new com.acme.MockUserTransaction());
|
||||
|
||||
// Define an env entry with webapp scope.
|
||||
new EnvEntry(webapp, "maxAmount", new Double(100), true);
|
||||
// THIS ENTRY IS OVERRIDEN BY THE ENTRY IN jetty-env.xml
|
||||
new EnvEntry(webapp, "maxAmount", 100d, true);
|
||||
|
||||
// Register a mock DataSource scoped to the webapp
|
||||
new Resource(webapp, "jdbc/mydatasource", new com.acme.MockDataSource());
|
||||
new Resource(server, "jdbc/mydatasource", new com.acme.MockDataSource());
|
||||
|
||||
// Add JNDI context to server for dump
|
||||
server.addBean(new NamingDump());
|
||||
|
||||
// Configure a LoginService
|
||||
HashLoginService loginService = new HashLoginService();
|
||||
|
@ -75,6 +78,7 @@ public class ServerWithAnnotations
|
|||
loginService.setConfig("examples/embedded/src/test/resources/realm.properties");
|
||||
server.addBean(loginService);
|
||||
|
||||
|
||||
server.start();
|
||||
server.dumpStdErr();
|
||||
server.join();
|
||||
|
|
|
@ -22,8 +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;
|
||||
|
@ -126,7 +128,7 @@ public class NamingContext implements Context, Dumpable
|
|||
this(env, name, parent, parser, null);
|
||||
}
|
||||
|
||||
private NamingContext(Hashtable<String,Object> env,
|
||||
protected NamingContext(Hashtable<String,Object> env,
|
||||
String name,
|
||||
NamingContext parent,
|
||||
NameParser parser,
|
||||
|
@ -143,14 +145,13 @@ public class NamingContext implements Context, Dumpable
|
|||
}
|
||||
|
||||
/**
|
||||
* @return A shallow copy of the Context with the same bindings, but a copy of the Env
|
||||
* @return A shallow copy of the Context with the same bindings, but with the passed environment
|
||||
*/
|
||||
public NamingContext shallowCopy()
|
||||
public Context shallowCopy(Hashtable<String, Object> env)
|
||||
{
|
||||
return new NamingContext(_env, _name, _parent, _parser, _bindings);
|
||||
return new NamingContext(env, _name, _parent, _parser, _bindings);
|
||||
}
|
||||
|
||||
|
||||
public boolean isDeepBindingSupported()
|
||||
{
|
||||
// look for deep binding support in _env
|
||||
|
@ -457,7 +458,7 @@ public class NamingContext implements Context, Dumpable
|
|||
{
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("Null or empty name, returning shallowCopy of this context");
|
||||
return shallowCopy();
|
||||
return shallowCopy(_env);
|
||||
}
|
||||
|
||||
if (cname.size() == 1)
|
||||
|
@ -541,7 +542,7 @@ public class NamingContext implements Context, Dumpable
|
|||
|
||||
if (cname == null || name.isEmpty())
|
||||
{
|
||||
return shallowCopy();
|
||||
return shallowCopy(_env);
|
||||
}
|
||||
|
||||
if (cname.size() == 0)
|
||||
|
@ -1118,7 +1119,17 @@ public class NamingContext implements Context, Dumpable
|
|||
@Override
|
||||
public void dump(Appendable out,String indent) throws IOException
|
||||
{
|
||||
Dumpable.dumpObjects(out,indent,this, _bindings);
|
||||
Map<String, Object> bindings = new HashMap<>();
|
||||
for (Map.Entry<String,Binding> binding : _bindings.entrySet())
|
||||
bindings.put(binding.getKey(), binding.getValue().getObject());
|
||||
|
||||
Dumpable.dumpObject(out, this);
|
||||
Dumpable.dumpMapEntries(out, indent, bindings, _env.isEmpty());
|
||||
if (!_env.isEmpty())
|
||||
{
|
||||
out.append(indent).append("+> environment\n");
|
||||
Dumpable.dumpMapEntries(out, indent + " ", _env, true);
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<Listener> findListeners()
|
||||
|
|
|
@ -270,7 +270,7 @@ public class localContextRoot implements Context
|
|||
if (cname == null || cname.isEmpty())
|
||||
{
|
||||
//If no name create copy of this context with same bindings, but with copy of the environment so it can be modified
|
||||
return __root.shallowCopy();
|
||||
return __root.shallowCopy(_env);
|
||||
}
|
||||
|
||||
if (cname.size() == 0)
|
||||
|
@ -339,7 +339,7 @@ public class localContextRoot implements Context
|
|||
|
||||
if ((cname == null) || cname.isEmpty())
|
||||
{
|
||||
return __root.shallowCopy();
|
||||
return __root.shallowCopy(_env);
|
||||
}
|
||||
|
||||
if (cname.size() == 1)
|
||||
|
|
|
@ -56,4 +56,10 @@ public class EnvEntry extends NamingEntry
|
|||
{
|
||||
return this.overrideWebXml;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toStringMetaData()
|
||||
{
|
||||
return "OverrideWebXml=" + overrideWebXml;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,4 +52,10 @@ public class Link extends NamingEntry
|
|||
{
|
||||
return _link;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toStringMetaData()
|
||||
{
|
||||
return _link;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.plus.jndi;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
|
||||
/**
|
||||
* A utility Dumpable to dump a JNDI naming context tree.
|
||||
*/
|
||||
public class NamingDump implements Dumpable
|
||||
{
|
||||
private final ClassLoader _loader;
|
||||
private final String _name;
|
||||
|
||||
public NamingDump()
|
||||
{
|
||||
this(null,"");
|
||||
}
|
||||
|
||||
public NamingDump(ClassLoader loader, String name)
|
||||
{
|
||||
_loader = loader;
|
||||
_name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent)
|
||||
{
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
try
|
||||
{
|
||||
if (!StringUtil.isBlank(_name))
|
||||
out.append(_name).append(" ");
|
||||
if (_loader!=null)
|
||||
Thread.currentThread().setContextClassLoader(_loader);
|
||||
Object context = new InitialContext().lookup(_name);
|
||||
if (context instanceof Dumpable)
|
||||
((Dumpable)context).dump(out, indent);
|
||||
else
|
||||
Dumpable.dumpObjects(out, indent, context);
|
||||
}
|
||||
catch(Throwable th)
|
||||
{
|
||||
throw new RuntimeException(th);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_loader!=null)
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,14 +49,7 @@ public abstract class NamingEntry
|
|||
protected String _namingEntryNameString; //the name of the NamingEntry relative to the context it is stored in
|
||||
protected String _objectNameString; //the name of the object relative to the context it is stored in
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return _jndiName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a naming entry.
|
||||
*
|
||||
|
@ -173,21 +166,21 @@ public abstract class NamingEntry
|
|||
/**
|
||||
* Save the NamingEntry for later use.
|
||||
* <p>
|
||||
* Saving is done by binding the NamingEntry
|
||||
* Saving is done by binding both the NamingEntry
|
||||
* itself, and the value it represents into
|
||||
* JNDI. In this way, we can link to the
|
||||
* value it represents later, but also
|
||||
* still retrieve the NamingEntry itself too.
|
||||
* <p>
|
||||
* The object is bound at the jndiName passed in.
|
||||
* This NamingEntry is bound at __/jndiName.
|
||||
* The object is bound at scope/jndiName and
|
||||
* the NamingEntry is bound at scope/__/jndiName.
|
||||
* <p>
|
||||
* eg
|
||||
* <pre>
|
||||
* jdbc/foo : DataSource
|
||||
* __/jdbc/foo : NamingEntry
|
||||
* </pre>
|
||||
*
|
||||
* @see NamingEntryUtil#getNameForScope(Object)
|
||||
* @param object the object to save
|
||||
* @throws NamingException if unable to save
|
||||
*/
|
||||
|
@ -212,5 +205,18 @@ public abstract class NamingEntry
|
|||
_objectNameString = objectName.toString();
|
||||
NamingUtil.bind(ic, _objectNameString, object);
|
||||
}
|
||||
|
||||
|
||||
protected String toStringMetaData()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String metadata = toStringMetaData();
|
||||
if (metadata == null)
|
||||
return String.format("%s@%x{name=%s}", this.getClass().getName(), hashCode(), getJndiName());
|
||||
return String.format("%s@%x{name=%s,%s}", this.getClass().getName(), hashCode(), getJndiName(), metadata);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ public class NamingEntryUtil
|
|||
* @return all NameEntries of a certain type in the given naming environment scope (server-wide names or context-specific names)
|
||||
* @throws NamingException if unable to lookup the naming entries
|
||||
*/
|
||||
public static List<Object> lookupNamingEntries (Object scope, Class<?> clazz)
|
||||
public static <T> List<? extends T> lookupNamingEntries (Object scope, Class<T> clazz)
|
||||
throws NamingException
|
||||
{
|
||||
try
|
||||
|
@ -127,7 +127,7 @@ public class NamingEntryUtil
|
|||
Context namingEntriesContext = (Context)scopeContext.lookup(NamingEntry.__contextName);
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
lookupNamingEntries(list, namingEntriesContext, clazz);
|
||||
return list;
|
||||
return (List<T>)list;
|
||||
}
|
||||
catch (NameNotFoundException e)
|
||||
{
|
||||
|
|
|
@ -21,9 +21,7 @@ package org.eclipse.jetty.plus.webapp;
|
|||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
|
@ -36,6 +34,7 @@ import org.eclipse.jetty.jndi.NamingContext;
|
|||
import org.eclipse.jetty.jndi.NamingUtil;
|
||||
import org.eclipse.jetty.jndi.local.localContextRoot;
|
||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
||||
import org.eclipse.jetty.plus.jndi.NamingDump;
|
||||
import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -54,6 +53,7 @@ public class EnvConfiguration extends AbstractConfiguration
|
|||
|
||||
private static final String JETTY_ENV_BINDINGS = "org.eclipse.jetty.jndi.EnvConfiguration";
|
||||
private URL jettyEnvXmlUrl;
|
||||
private NamingDump _dumper;
|
||||
|
||||
public void setJettyEnvXml (URL url)
|
||||
{
|
||||
|
@ -128,6 +128,9 @@ public class EnvConfiguration extends AbstractConfiguration
|
|||
|
||||
//add java:comp/env entries for any EnvEntries that have been defined so far
|
||||
bindEnvEntries(context);
|
||||
|
||||
_dumper = new NamingDump(context.getClassLoader(),"java:comp");
|
||||
context.addBean(_dumper);
|
||||
}
|
||||
|
||||
|
||||
|
@ -138,6 +141,9 @@ public class EnvConfiguration extends AbstractConfiguration
|
|||
@Override
|
||||
public void deconfigure (WebAppContext context) throws Exception
|
||||
{
|
||||
context.removeBean(_dumper);
|
||||
_dumper = null;
|
||||
|
||||
//get rid of any bindings for comp/env for webapp
|
||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||
|
@ -206,40 +212,23 @@ public class EnvConfiguration extends AbstractConfiguration
|
|||
public void bindEnvEntries (WebAppContext context)
|
||||
throws NamingException
|
||||
{
|
||||
LOG.debug("Binding env entries from the jvm scope");
|
||||
InitialContext ic = new InitialContext();
|
||||
Context envCtx = (Context)ic.lookup("java:comp/env");
|
||||
Object scope = null;
|
||||
List<Object> list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
||||
Iterator<Object> itor = list.iterator();
|
||||
while (itor.hasNext())
|
||||
{
|
||||
EnvEntry ee = (EnvEntry)itor.next();
|
||||
ee.bindToENC(ee.getJndiName());
|
||||
Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, ee);
|
||||
NamingUtil.bind(envCtx, namingEntryName.toString(), ee);//also save the EnvEntry in the context so we can check it later
|
||||
}
|
||||
|
||||
LOG.debug("Binding env entries from the jvm scope");
|
||||
doBindings(envCtx, null);
|
||||
|
||||
LOG.debug("Binding env entries from the server scope");
|
||||
|
||||
scope = context.getServer();
|
||||
list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
||||
itor = list.iterator();
|
||||
while (itor.hasNext())
|
||||
{
|
||||
EnvEntry ee = (EnvEntry)itor.next();
|
||||
ee.bindToENC(ee.getJndiName());
|
||||
Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, ee);
|
||||
NamingUtil.bind(envCtx, namingEntryName.toString(), ee);//also save the EnvEntry in the context so we can check it later
|
||||
}
|
||||
doBindings(envCtx, context.getServer());
|
||||
|
||||
LOG.debug("Binding env entries from the context scope");
|
||||
scope = context;
|
||||
list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
||||
itor = list.iterator();
|
||||
while (itor.hasNext())
|
||||
doBindings(envCtx, context);
|
||||
}
|
||||
|
||||
private void doBindings(Context envCtx, Object scope) throws NamingException
|
||||
{
|
||||
for (EnvEntry ee : NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class))
|
||||
{
|
||||
EnvEntry ee = (EnvEntry)itor.next();
|
||||
ee.bindToENC(ee.getJndiName());
|
||||
Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, ee);
|
||||
NamingUtil.bind(envCtx, namingEntryName.toString(), ee);//also save the EnvEntry in the context so we can check it later
|
||||
|
|
|
@ -22,5 +22,9 @@
|
|||
</Call>
|
||||
</Call>
|
||||
|
||||
<Call name="addBean">
|
||||
<Arg><New class="org.eclipse.jetty.plus.jndi.NamingDump"/></Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
||||
|
||||
|
|
|
@ -18,6 +18,15 @@
|
|||
|
||||
package org.eclipse.jetty.plus.jndi;
|
||||
|
||||
import java.util.List;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
|
@ -27,16 +36,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TestNamingEntryUtil
|
||||
{
|
||||
public class MyNamingEntry extends NamingEntry
|
||||
|
@ -122,7 +121,7 @@ public class TestNamingEntryUtil
|
|||
public void testLookupNamingEntries() throws Exception
|
||||
{
|
||||
ScopeA scope = new ScopeA();
|
||||
List<?> list = NamingEntryUtil.lookupNamingEntries(scope, MyNamingEntry.class);
|
||||
List<? extends MyNamingEntry> list = NamingEntryUtil.lookupNamingEntries(scope, MyNamingEntry.class);
|
||||
assertThat(list, is(empty()));
|
||||
|
||||
MyNamingEntry mne1 = new MyNamingEntry(scope, "a/b", 1);
|
||||
|
|
|
@ -18,6 +18,15 @@
|
|||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
@ -29,15 +38,6 @@ import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
|||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -135,7 +135,7 @@ public class LowResourceMonitor extends ContainerLifeCycle
|
|||
|
||||
/**
|
||||
* @param maxConnections The maximum connections before low resources state is triggered
|
||||
* @deprecated Replaced by ConnectionLimit
|
||||
* @deprecated Replaced by {@link ConnectionLimit}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setMaxConnections(int maxConnections)
|
||||
|
|
|
@ -28,7 +28,6 @@ import java.util.Enumeration;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -47,7 +46,6 @@ import org.eclipse.jetty.server.handler.ErrorHandler;
|
|||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.MultiException;
|
||||
import org.eclipse.jetty.util.URIUtil;
|
||||
|
@ -55,6 +53,7 @@ import org.eclipse.jetty.util.Uptime;
|
|||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.annotation.Name;
|
||||
import org.eclipse.jetty.util.component.AttributeContainerMap;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -75,7 +74,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(Server.class);
|
||||
|
||||
private final AttributesMap _attributes = new AttributesMap();
|
||||
private final AttributeContainerMap _attributes = new AttributeContainerMap();
|
||||
private final ThreadPool _threadPool;
|
||||
private final List<Connector> _connectors = new CopyOnWriteArrayList<>();
|
||||
private SessionIdManager _sessionIdManager;
|
||||
|
@ -107,6 +106,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
ServerConnector connector=new ServerConnector(this);
|
||||
connector.setPort(port);
|
||||
setConnectors(new Connector[]{connector});
|
||||
addBean(_attributes);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -584,9 +584,6 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
@Override
|
||||
public void clearAttributes()
|
||||
{
|
||||
Enumeration<String> names = _attributes.getAttributeNames();
|
||||
while (names.hasMoreElements())
|
||||
removeBean(_attributes.getAttribute(names.nextElement()));
|
||||
_attributes.clearAttributes();
|
||||
}
|
||||
|
||||
|
@ -607,7 +604,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
@Override
|
||||
public Enumeration<String> getAttributeNames()
|
||||
{
|
||||
return AttributesMap.getAttributeNamesCopy(_attributes);
|
||||
return _attributes.getAttributeNames();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -617,9 +614,6 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
@Override
|
||||
public void removeAttribute(String name)
|
||||
{
|
||||
Object bean=_attributes.getAttribute(name);
|
||||
if (bean!=null)
|
||||
removeBean(bean);
|
||||
_attributes.removeAttribute(name);
|
||||
}
|
||||
|
||||
|
@ -630,9 +624,6 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
@Override
|
||||
public void setAttribute(String name, Object attribute)
|
||||
{
|
||||
// TODO this is a crude way to get attribute values managed by JMX.
|
||||
Object old=_attributes.getAttribute(name);
|
||||
updateBean(old,attribute);
|
||||
_attributes.setAttribute(name, attribute);
|
||||
}
|
||||
|
||||
|
@ -693,7 +684,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
@Override
|
||||
public void dump(Appendable out,String indent) throws IOException
|
||||
{
|
||||
dumpObjects(out,indent,new ClassLoaderDump(this.getClass().getClassLoader()),_attributes);
|
||||
dumpObjects(out,indent,new ClassLoaderDump(this.getClass().getClassLoader()));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -714,6 +705,5 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
_seconds = seconds;
|
||||
_dateField = dateField;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
|
||||
/**
|
||||
* An Attributes implementation that holds it's values in an immutable {@link ContainerLifeCycle}
|
||||
*/
|
||||
public class AttributeContainerMap extends ContainerLifeCycle implements Attributes
|
||||
{
|
||||
private final Map<String, Object> _map = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public synchronized void setAttribute(String name, Object attribute)
|
||||
{
|
||||
Object old = _map.put(name, attribute);
|
||||
updateBean(old, attribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeAttribute(String name)
|
||||
{
|
||||
Object removed = _map.remove(name);
|
||||
if (removed != null)
|
||||
removeBean(removed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object getAttribute(String name)
|
||||
{
|
||||
return _map.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Enumeration<String> getAttributeNames()
|
||||
{
|
||||
return Collections.enumeration(_map.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clearAttributes()
|
||||
{
|
||||
_map.clear();
|
||||
this.removeBeans();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
Dumpable.dumpObject(out, this);
|
||||
Dumpable.dumpMapEntries(out, indent, _map, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("%s@%x{size=%d}",this.getClass().getSimpleName(),hashCode(),_map.size());
|
||||
}
|
||||
}
|
|
@ -132,7 +132,7 @@ public interface Container
|
|||
|
||||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @return the list of beans of the given class from the entire managed hierarchy
|
||||
* @return the list of beans of the given class from the entire Container hierarchy
|
||||
* @param <T> the Bean type
|
||||
*/
|
||||
public <T> Collection<T> getContainedBeans(Class<T> clazz);
|
||||
|
|
|
@ -550,13 +550,17 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
@Override
|
||||
public <T> Collection<T> getBeans(Class<T> clazz)
|
||||
{
|
||||
ArrayList<T> beans = new ArrayList<>();
|
||||
ArrayList<T> beans = null;
|
||||
for (Bean b : _beans)
|
||||
{
|
||||
if (clazz.isInstance(b._bean))
|
||||
{
|
||||
if (beans == null)
|
||||
beans = new ArrayList<>();
|
||||
beans.add(clazz.cast(b._bean));
|
||||
}
|
||||
}
|
||||
return beans;
|
||||
return beans == null ? Collections.emptyList() : beans;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -879,7 +883,7 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
|
||||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @return the list of beans of the given class from the entire managed hierarchy
|
||||
* @return the list of beans of the given class from the entire Container hierarchy
|
||||
* @param <T> the Bean type
|
||||
*/
|
||||
@Override
|
||||
|
@ -893,7 +897,7 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @param beans the collection to add beans of the given class from the entire managed hierarchy
|
||||
* @param beans the collection to add beans of the given class from the entire Container hierarchy
|
||||
*/
|
||||
protected <T> void getContainedBeans(Class<T> clazz, Collection<T> beans)
|
||||
{
|
||||
|
|
|
@ -93,18 +93,19 @@ public interface Dumpable
|
|||
String s;
|
||||
if (o==null)
|
||||
s = "null";
|
||||
else if (o instanceof Collection)
|
||||
s = String.format("%s@%x(size=%d)",o.getClass().getName(),o.hashCode(),((Collection)o).size());
|
||||
else if (o.getClass().isArray())
|
||||
s = String.format("%s@%x[size=%d]",o.getClass().getComponentType(),o.hashCode(), Array.getLength(o));
|
||||
else if (o instanceof Map)
|
||||
s = String.format("%s@%x{size=%d}",o.getClass().getName(),o.hashCode(),((Map<?,?>)o).size());
|
||||
else if (o instanceof Dumpable)
|
||||
{
|
||||
s = ((Dumpable)o).dumpSelf();
|
||||
s = StringUtil.replace(s, "\r\n", "|");
|
||||
s = StringUtil.replace(s, '\n', '|');
|
||||
}
|
||||
else if (o instanceof Collection)
|
||||
s = String.format("%s@%x(size=%d)",o.getClass().getName(),o.hashCode(),((Collection)o).size());
|
||||
else if (o.getClass().isArray())
|
||||
s = String.format("%s@%x[size=%d]",o.getClass().getComponentType(),o.hashCode(), Array.getLength(o));
|
||||
else if (o instanceof Map)
|
||||
s = String.format("%s@%x{size=%d}",o.getClass().getName(),o.hashCode(),((Map<?,?>)o).size());
|
||||
|
||||
else
|
||||
{
|
||||
s = String.valueOf(o);
|
||||
|
@ -139,7 +140,7 @@ public interface Dumpable
|
|||
{
|
||||
dumpObject(out,object);
|
||||
|
||||
int size = extraChildren==null?0:extraChildren.length;
|
||||
int extras = extraChildren==null?0:extraChildren.length;
|
||||
|
||||
if (object instanceof Stream)
|
||||
object = ((Stream)object).toArray();
|
||||
|
@ -148,87 +149,25 @@ public interface Dumpable
|
|||
|
||||
if (object instanceof Container)
|
||||
{
|
||||
Container container = (Container)object;
|
||||
ContainerLifeCycle containerLifeCycle = container instanceof ContainerLifeCycle ? (ContainerLifeCycle)container : null;
|
||||
for (Iterator<Object> i = container.getBeans().iterator(); i.hasNext();)
|
||||
{
|
||||
Object bean = i.next();
|
||||
String nextIndent = indent + ((i.hasNext() || size>0) ? "| " : " ");
|
||||
if (bean instanceof LifeCycle)
|
||||
{
|
||||
if (container.isManaged(bean))
|
||||
{
|
||||
out.append(indent).append("+= ");
|
||||
if (bean instanceof Dumpable)
|
||||
((Dumpable)bean).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out, nextIndent, bean);
|
||||
}
|
||||
else if (containerLifeCycle != null && containerLifeCycle.isAuto(bean))
|
||||
{
|
||||
out.append(indent).append("+? ");
|
||||
if (bean instanceof Dumpable)
|
||||
((Dumpable)bean).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out, nextIndent, bean);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.append(indent).append("+~ ");
|
||||
dumpObject(out, bean);
|
||||
}
|
||||
}
|
||||
else if (containerLifeCycle != null && containerLifeCycle.isUnmanaged(bean))
|
||||
{
|
||||
out.append(indent).append("+~ ");
|
||||
dumpObject(out, bean);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.append(indent).append("+- ");
|
||||
if (bean instanceof Dumpable)
|
||||
((Dumpable)bean).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out, nextIndent, bean);
|
||||
}
|
||||
}
|
||||
dumpContainer(out, indent, (Container)object, extras==0);
|
||||
}
|
||||
if (object instanceof Iterable)
|
||||
{
|
||||
for (Iterator i = ((Iterable<?>)object).iterator(); i.hasNext();)
|
||||
{
|
||||
Object item = i.next();
|
||||
String nextIndent = indent + ((i.hasNext() || size>0) ? "| " : " ");
|
||||
out.append(indent).append("+: ");
|
||||
if (item instanceof Dumpable)
|
||||
((Dumpable)item).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out,nextIndent, item);
|
||||
}
|
||||
dumpIterable(out, indent, (Iterable<?>)object, extras==0);
|
||||
}
|
||||
else if (object instanceof Map)
|
||||
{
|
||||
for (Iterator<? extends Map.Entry<?, ?>> i = ((Map<?,?>)object).entrySet().iterator(); i.hasNext();)
|
||||
{
|
||||
Map.Entry entry = i.next();
|
||||
String nextIndent = indent + ((i.hasNext() || size>0) ? "| " : " ");
|
||||
out.append(indent).append("+@ ").append(String.valueOf(entry.getKey())).append('=');
|
||||
Object item = entry.getValue();
|
||||
if (item instanceof Dumpable)
|
||||
((Dumpable)item).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out,nextIndent, item);
|
||||
}
|
||||
dumpMapEntries(out, indent, (Map<?,?>)object, extras==0);
|
||||
}
|
||||
|
||||
if (size==0)
|
||||
if (extras==0)
|
||||
return;
|
||||
|
||||
int i = 0;
|
||||
for (Object item : extraChildren)
|
||||
{
|
||||
i++;
|
||||
String nextIndent = indent + (i<size ? "| " : " ");
|
||||
String nextIndent = indent + (i<extras ? "| " : " ");
|
||||
out.append(indent).append("+> ");
|
||||
if (item instanceof Dumpable)
|
||||
((Dumpable)item).dump(out,nextIndent);
|
||||
|
@ -236,4 +175,91 @@ public interface Dumpable
|
|||
dumpObjects(out, nextIndent, item);
|
||||
}
|
||||
}
|
||||
|
||||
static void dumpContainer(Appendable out, String indent, Container object, boolean last) throws IOException
|
||||
{
|
||||
Container container = object;
|
||||
ContainerLifeCycle containerLifeCycle = container instanceof ContainerLifeCycle ? (ContainerLifeCycle)container : null;
|
||||
for (Iterator<Object> i = container.getBeans().iterator(); i.hasNext();)
|
||||
{
|
||||
Object bean = i.next();
|
||||
String nextIndent = indent + ((i.hasNext() || !last) ? "| " : " ");
|
||||
if (bean instanceof LifeCycle)
|
||||
{
|
||||
if (container.isManaged(bean))
|
||||
{
|
||||
out.append(indent).append("+= ");
|
||||
if (bean instanceof Dumpable)
|
||||
((Dumpable)bean).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out, nextIndent, bean);
|
||||
}
|
||||
else if (containerLifeCycle != null && containerLifeCycle.isAuto(bean))
|
||||
{
|
||||
out.append(indent).append("+? ");
|
||||
if (bean instanceof Dumpable)
|
||||
((Dumpable)bean).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out, nextIndent, bean);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.append(indent).append("+~ ");
|
||||
dumpObject(out, bean);
|
||||
}
|
||||
}
|
||||
else if (containerLifeCycle != null && containerLifeCycle.isUnmanaged(bean))
|
||||
{
|
||||
out.append(indent).append("+~ ");
|
||||
dumpObject(out, bean);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.append(indent).append("+- ");
|
||||
if (bean instanceof Dumpable)
|
||||
((Dumpable)bean).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out, nextIndent, bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dumpIterable(Appendable out, String indent, Iterable<?> iterable, boolean last) throws IOException
|
||||
{
|
||||
for (Iterator i = iterable.iterator(); i.hasNext();)
|
||||
{
|
||||
Object item = i.next();
|
||||
String nextIndent = indent + ((i.hasNext() || !last) ? "| " : " ");
|
||||
out.append(indent).append("+: ");
|
||||
if (item instanceof Dumpable)
|
||||
((Dumpable)item).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out,nextIndent, item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void dumpMapEntries(Appendable out, String indent, Map<?,?> map, boolean last) throws IOException
|
||||
{
|
||||
for (Iterator<? extends Map.Entry<?, ?>> i = map.entrySet().iterator(); i.hasNext();)
|
||||
{
|
||||
Map.Entry entry = i.next();
|
||||
String nextIndent = indent + ((i.hasNext() || !last) ? "| " : " ");
|
||||
out.append(indent).append("+@ ").append(String.valueOf(entry.getKey())).append(" = ");
|
||||
Object item = entry.getValue();
|
||||
if (item instanceof Dumpable)
|
||||
((Dumpable)item).dump(out,nextIndent);
|
||||
else
|
||||
dumpObjects(out,nextIndent, item);
|
||||
}
|
||||
}
|
||||
|
||||
static Dumpable named(String name, Object object)
|
||||
{
|
||||
return (out, indent) ->
|
||||
{
|
||||
out.append(name).append(": ");
|
||||
Dumpable.dumpObjects(out, indent, object);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -724,7 +724,7 @@ public class WebAppClassLoader extends URLClassLoader implements ClassVisibility
|
|||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "WebAppClassLoader=" + _name+"@"+Long.toHexString(hashCode());
|
||||
return String.format("%s{%s}@%x", this.getClass().getSimpleName(), _name, hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,7 +34,6 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRegistration.Dynamic;
|
||||
import javax.servlet.ServletSecurityElement;
|
||||
|
@ -1040,15 +1039,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
public String toString()
|
||||
{
|
||||
if (_war!=null)
|
||||
{
|
||||
String war=_war;
|
||||
if (war.indexOf("/webapps/")>=0)
|
||||
war=war.substring(war.indexOf("/webapps/")+8);
|
||||
return super.toString()+"{"+war+"}";
|
||||
}
|
||||
return super.toString()+"{"+_war+"}";
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
|
@ -1066,15 +1060,39 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
server_classes=new ArrayList<>(_serverClasses);
|
||||
Collections.sort(server_classes);
|
||||
}
|
||||
|
||||
|
||||
String name = getDisplayName();
|
||||
if (name == null)
|
||||
{
|
||||
if (_war != null)
|
||||
{
|
||||
if (_war.indexOf("/webapps/") >= 0)
|
||||
name = _war.substring(_war.indexOf("/webapps/") + 8);
|
||||
else
|
||||
name = _war;
|
||||
}
|
||||
else if (getResourceBase() != null)
|
||||
{
|
||||
name = getResourceBase();
|
||||
if (name.indexOf("/webapps/") >= 0)
|
||||
name = name.substring(name.indexOf("/webapps/") + 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = this.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
|
||||
name = String.format("%s@%x", name, hashCode());
|
||||
|
||||
dumpObjects(out,indent,
|
||||
new ClassLoaderDump(getClassLoader()),
|
||||
new DumpableCollection("Systemclasses "+this,system_classes),
|
||||
new DumpableCollection("Serverclasses "+this,server_classes),
|
||||
new DumpableCollection("Configurations "+this,_configurations),
|
||||
new DumpableCollection("Handler attributes "+this,((AttributesMap)getAttributes()).getAttributeEntrySet()),
|
||||
new DumpableCollection("Context attributes "+this,((Context)getServletContext()).getAttributeEntrySet()),
|
||||
new DumpableCollection("Initparams "+this,getInitParams().entrySet())
|
||||
new DumpableCollection("Systemclasses " + name, system_classes),
|
||||
new DumpableCollection("Serverclasses " + name, server_classes),
|
||||
new DumpableCollection("Configurations " + name, _configurations),
|
||||
new DumpableCollection("Handler attributes " + name, ((AttributesMap)getAttributes()).getAttributeEntrySet()),
|
||||
new DumpableCollection("Context attributes " + name, ((Context)getServletContext()).getAttributeEntrySet()),
|
||||
new DumpableCollection("Initparams " + name, getInitParams().entrySet())
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue