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;
|
package org.eclipse.jetty.embedded;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
|
|
||||||
import org.eclipse.jetty.deploy.DeploymentManager;
|
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||||
|
@ -60,27 +59,14 @@ public class LikeJettyXml
|
||||||
public static void main( String[] args ) throws Exception
|
public static void main( String[] args ) throws Exception
|
||||||
{
|
{
|
||||||
// Path to as-built jetty-distribution directory
|
// Path to as-built jetty-distribution directory
|
||||||
String jettyHomeBuild = "jetty-distribution/target/distribution";
|
String jettyHomeBuild = JettyDistribution.DISTRIBUTION.toString();
|
||||||
|
|
||||||
// Find jetty home and base directories
|
// Find jetty home and base directories
|
||||||
String homePath = System.getProperty("jetty.home", jettyHomeBuild);
|
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);
|
File homeDir = new File(homePath);
|
||||||
|
|
||||||
String basePath = System.getProperty("jetty.base", homeDir + "/demo-base");
|
String basePath = System.getProperty("jetty.base", homeDir + "/demo-base");
|
||||||
File baseDir = new File(basePath);
|
File baseDir = new File(basePath);
|
||||||
if(!baseDir.exists())
|
|
||||||
{
|
|
||||||
throw new FileNotFoundException(baseDir.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure jetty.home and jetty.base system properties
|
// Configure jetty.home and jetty.base system properties
|
||||||
String jetty_home = homeDir.getAbsolutePath();
|
String jetty_home = homeDir.getAbsolutePath();
|
||||||
|
@ -88,7 +74,6 @@ public class LikeJettyXml
|
||||||
System.setProperty("jetty.home", jetty_home);
|
System.setProperty("jetty.home", jetty_home);
|
||||||
System.setProperty("jetty.base", jetty_base);
|
System.setProperty("jetty.base", jetty_base);
|
||||||
|
|
||||||
|
|
||||||
// === jetty.xml ===
|
// === jetty.xml ===
|
||||||
// Setup Threadpool
|
// Setup Threadpool
|
||||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||||
|
@ -219,7 +204,6 @@ public class LikeJettyXml
|
||||||
lowResourcesMonitor.setPeriod(1000);
|
lowResourcesMonitor.setPeriod(1000);
|
||||||
lowResourcesMonitor.setLowResourcesIdleTimeout(200);
|
lowResourcesMonitor.setLowResourcesIdleTimeout(200);
|
||||||
lowResourcesMonitor.setMonitorThreads(true);
|
lowResourcesMonitor.setMonitorThreads(true);
|
||||||
lowResourcesMonitor.setMaxConnections(0);
|
|
||||||
lowResourcesMonitor.setMaxMemory(0);
|
lowResourcesMonitor.setMaxMemory(0);
|
||||||
lowResourcesMonitor.setMaxLowResourcesTime(5000);
|
lowResourcesMonitor.setMaxLowResourcesTime(5000);
|
||||||
server.addBean(lowResourcesMonitor);
|
server.addBean(lowResourcesMonitor);
|
||||||
|
|
|
@ -49,8 +49,7 @@ public class OneWebApp
|
||||||
// PlusConfiguration) to choosing where the webapp will unpack itself.
|
// PlusConfiguration) to choosing where the webapp will unpack itself.
|
||||||
WebAppContext webapp = new WebAppContext();
|
WebAppContext webapp = new WebAppContext();
|
||||||
webapp.setContextPath("/");
|
webapp.setContextPath("/");
|
||||||
File warFile = new File(
|
File warFile = JettyDistribution.resolve("demo-base/webapps/async-rest.war").toFile();
|
||||||
"../../tests/test-jmx/jmx-webapp/target/jmx-webapp");
|
|
||||||
webapp.setWar(warFile.getAbsolutePath());
|
webapp.setWar(warFile.getAbsolutePath());
|
||||||
|
|
||||||
// A WebAppContext is a ContextHandler as well so it needs to be set to
|
// 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 java.io.File;
|
||||||
|
|
||||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
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.Resource;
|
||||||
import org.eclipse.jetty.plus.jndi.Transaction;
|
import org.eclipse.jetty.plus.jndi.Transaction;
|
||||||
import org.eclipse.jetty.security.HashLoginService;
|
import org.eclipse.jetty.security.HashLoginService;
|
||||||
|
@ -47,16 +48,14 @@ public class ServerWithAnnotations
|
||||||
classlist.addBefore(
|
classlist.addBefore(
|
||||||
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
|
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
|
||||||
"org.eclipse.jetty.annotations.AnnotationConfiguration");
|
"org.eclipse.jetty.annotations.AnnotationConfiguration");
|
||||||
|
|
||||||
// Create a WebApp
|
// Create a WebApp
|
||||||
WebAppContext webapp = new WebAppContext();
|
WebAppContext webapp = new WebAppContext();
|
||||||
webapp.setContextPath("/");
|
webapp.setContextPath("/");
|
||||||
File warFile = new File(
|
File warFile = JettyDistribution.resolve("demo-base/webapps/test-spec.war").toFile();
|
||||||
"jetty-distribution/target/distribution/demo-base/webapps/test.war");
|
|
||||||
webapp.setWar(warFile.getAbsolutePath());
|
webapp.setWar(warFile.getAbsolutePath());
|
||||||
webapp.setAttribute(
|
webapp.setAttribute(
|
||||||
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
|
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
|
||||||
".*/javax.servlet-[^/]*\\.jar$|.*/servlet-api-[^/]*\\.jar$");
|
".*/javax.servlet-[^/]*\\.jar$|.*/servlet-api-[^/]*\\.jar$");
|
||||||
server.setHandler(webapp);
|
server.setHandler(webapp);
|
||||||
|
|
||||||
// Register new transaction manager in JNDI
|
// Register new transaction manager in JNDI
|
||||||
|
@ -64,10 +63,14 @@ public class ServerWithAnnotations
|
||||||
new Transaction(new com.acme.MockUserTransaction());
|
new Transaction(new com.acme.MockUserTransaction());
|
||||||
|
|
||||||
// Define an env entry with webapp scope.
|
// 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
|
// 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
|
// Configure a LoginService
|
||||||
HashLoginService loginService = new HashLoginService();
|
HashLoginService loginService = new HashLoginService();
|
||||||
|
@ -75,6 +78,7 @@ public class ServerWithAnnotations
|
||||||
loginService.setConfig("examples/embedded/src/test/resources/realm.properties");
|
loginService.setConfig("examples/embedded/src/test/resources/realm.properties");
|
||||||
server.addBean(loginService);
|
server.addBean(loginService);
|
||||||
|
|
||||||
|
|
||||||
server.start();
|
server.start();
|
||||||
server.dumpStdErr();
|
server.dumpStdErr();
|
||||||
server.join();
|
server.join();
|
||||||
|
|
|
@ -22,8 +22,10 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import javax.naming.Binding;
|
import javax.naming.Binding;
|
||||||
|
@ -126,7 +128,7 @@ public class NamingContext implements Context, Dumpable
|
||||||
this(env, name, parent, parser, null);
|
this(env, name, parent, parser, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamingContext(Hashtable<String,Object> env,
|
protected NamingContext(Hashtable<String,Object> env,
|
||||||
String name,
|
String name,
|
||||||
NamingContext parent,
|
NamingContext parent,
|
||||||
NameParser parser,
|
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()
|
public boolean isDeepBindingSupported()
|
||||||
{
|
{
|
||||||
// look for deep binding support in _env
|
// look for deep binding support in _env
|
||||||
|
@ -457,7 +458,7 @@ public class NamingContext implements Context, Dumpable
|
||||||
{
|
{
|
||||||
if(LOG.isDebugEnabled())
|
if(LOG.isDebugEnabled())
|
||||||
LOG.debug("Null or empty name, returning shallowCopy of this context");
|
LOG.debug("Null or empty name, returning shallowCopy of this context");
|
||||||
return shallowCopy();
|
return shallowCopy(_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cname.size() == 1)
|
if (cname.size() == 1)
|
||||||
|
@ -541,7 +542,7 @@ public class NamingContext implements Context, Dumpable
|
||||||
|
|
||||||
if (cname == null || name.isEmpty())
|
if (cname == null || name.isEmpty())
|
||||||
{
|
{
|
||||||
return shallowCopy();
|
return shallowCopy(_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cname.size() == 0)
|
if (cname.size() == 0)
|
||||||
|
@ -1118,7 +1119,17 @@ public class NamingContext implements Context, Dumpable
|
||||||
@Override
|
@Override
|
||||||
public void dump(Appendable out,String indent) throws IOException
|
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()
|
private Collection<Listener> findListeners()
|
||||||
|
|
|
@ -270,7 +270,7 @@ public class localContextRoot implements Context
|
||||||
if (cname == null || cname.isEmpty())
|
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
|
//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)
|
if (cname.size() == 0)
|
||||||
|
@ -339,7 +339,7 @@ public class localContextRoot implements Context
|
||||||
|
|
||||||
if ((cname == null) || cname.isEmpty())
|
if ((cname == null) || cname.isEmpty())
|
||||||
{
|
{
|
||||||
return __root.shallowCopy();
|
return __root.shallowCopy(_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cname.size() == 1)
|
if (cname.size() == 1)
|
||||||
|
|
|
@ -56,4 +56,10 @@ public class EnvEntry extends NamingEntry
|
||||||
{
|
{
|
||||||
return this.overrideWebXml;
|
return this.overrideWebXml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String toStringMetaData()
|
||||||
|
{
|
||||||
|
return "OverrideWebXml=" + overrideWebXml;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,4 +52,10 @@ public class Link extends NamingEntry
|
||||||
{
|
{
|
||||||
return _link;
|
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 _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
|
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.
|
* Create a naming entry.
|
||||||
*
|
*
|
||||||
|
@ -173,21 +166,21 @@ public abstract class NamingEntry
|
||||||
/**
|
/**
|
||||||
* Save the NamingEntry for later use.
|
* Save the NamingEntry for later use.
|
||||||
* <p>
|
* <p>
|
||||||
* Saving is done by binding the NamingEntry
|
* Saving is done by binding both the NamingEntry
|
||||||
* itself, and the value it represents into
|
* itself, and the value it represents into
|
||||||
* JNDI. In this way, we can link to the
|
* JNDI. In this way, we can link to the
|
||||||
* value it represents later, but also
|
* value it represents later, but also
|
||||||
* still retrieve the NamingEntry itself too.
|
* still retrieve the NamingEntry itself too.
|
||||||
* <p>
|
* <p>
|
||||||
* The object is bound at the jndiName passed in.
|
* The object is bound at scope/jndiName and
|
||||||
* This NamingEntry is bound at __/jndiName.
|
* the NamingEntry is bound at scope/__/jndiName.
|
||||||
* <p>
|
* <p>
|
||||||
* eg
|
* eg
|
||||||
* <pre>
|
* <pre>
|
||||||
* jdbc/foo : DataSource
|
* jdbc/foo : DataSource
|
||||||
* __/jdbc/foo : NamingEntry
|
* __/jdbc/foo : NamingEntry
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
* @see NamingEntryUtil#getNameForScope(Object)
|
||||||
* @param object the object to save
|
* @param object the object to save
|
||||||
* @throws NamingException if unable to save
|
* @throws NamingException if unable to save
|
||||||
*/
|
*/
|
||||||
|
@ -212,5 +205,18 @@ public abstract class NamingEntry
|
||||||
_objectNameString = objectName.toString();
|
_objectNameString = objectName.toString();
|
||||||
NamingUtil.bind(ic, _objectNameString, object);
|
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)
|
* @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
|
* @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
|
throws NamingException
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -127,7 +127,7 @@ public class NamingEntryUtil
|
||||||
Context namingEntriesContext = (Context)scopeContext.lookup(NamingEntry.__contextName);
|
Context namingEntriesContext = (Context)scopeContext.lookup(NamingEntry.__contextName);
|
||||||
ArrayList<Object> list = new ArrayList<Object>();
|
ArrayList<Object> list = new ArrayList<Object>();
|
||||||
lookupNamingEntries(list, namingEntriesContext, clazz);
|
lookupNamingEntries(list, namingEntriesContext, clazz);
|
||||||
return list;
|
return (List<T>)list;
|
||||||
}
|
}
|
||||||
catch (NameNotFoundException e)
|
catch (NameNotFoundException e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,9 +21,7 @@ package org.eclipse.jetty.plus.webapp;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.naming.Binding;
|
import javax.naming.Binding;
|
||||||
import javax.naming.Context;
|
import javax.naming.Context;
|
||||||
import javax.naming.InitialContext;
|
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.NamingUtil;
|
||||||
import org.eclipse.jetty.jndi.local.localContextRoot;
|
import org.eclipse.jetty.jndi.local.localContextRoot;
|
||||||
import org.eclipse.jetty.plus.jndi.EnvEntry;
|
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.plus.jndi.NamingEntryUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
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 static final String JETTY_ENV_BINDINGS = "org.eclipse.jetty.jndi.EnvConfiguration";
|
||||||
private URL jettyEnvXmlUrl;
|
private URL jettyEnvXmlUrl;
|
||||||
|
private NamingDump _dumper;
|
||||||
|
|
||||||
public void setJettyEnvXml (URL url)
|
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
|
//add java:comp/env entries for any EnvEntries that have been defined so far
|
||||||
bindEnvEntries(context);
|
bindEnvEntries(context);
|
||||||
|
|
||||||
|
_dumper = new NamingDump(context.getClassLoader(),"java:comp");
|
||||||
|
context.addBean(_dumper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,6 +141,9 @@ public class EnvConfiguration extends AbstractConfiguration
|
||||||
@Override
|
@Override
|
||||||
public void deconfigure (WebAppContext context) throws Exception
|
public void deconfigure (WebAppContext context) throws Exception
|
||||||
{
|
{
|
||||||
|
context.removeBean(_dumper);
|
||||||
|
_dumper = null;
|
||||||
|
|
||||||
//get rid of any bindings for comp/env for webapp
|
//get rid of any bindings for comp/env for webapp
|
||||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||||
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||||
|
@ -206,40 +212,23 @@ public class EnvConfiguration extends AbstractConfiguration
|
||||||
public void bindEnvEntries (WebAppContext context)
|
public void bindEnvEntries (WebAppContext context)
|
||||||
throws NamingException
|
throws NamingException
|
||||||
{
|
{
|
||||||
LOG.debug("Binding env entries from the jvm scope");
|
|
||||||
InitialContext ic = new InitialContext();
|
InitialContext ic = new InitialContext();
|
||||||
Context envCtx = (Context)ic.lookup("java:comp/env");
|
Context envCtx = (Context)ic.lookup("java:comp/env");
|
||||||
Object scope = null;
|
|
||||||
List<Object> list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
LOG.debug("Binding env entries from the jvm scope");
|
||||||
Iterator<Object> itor = list.iterator();
|
doBindings(envCtx, null);
|
||||||
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 server scope");
|
LOG.debug("Binding env entries from the server scope");
|
||||||
|
doBindings(envCtx, context.getServer());
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.debug("Binding env entries from the context scope");
|
LOG.debug("Binding env entries from the context scope");
|
||||||
scope = context;
|
doBindings(envCtx, context);
|
||||||
list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
|
}
|
||||||
itor = list.iterator();
|
|
||||||
while (itor.hasNext())
|
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());
|
ee.bindToENC(ee.getJndiName());
|
||||||
Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, ee);
|
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
|
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>
|
</Call>
|
||||||
|
|
||||||
|
<Call name="addBean">
|
||||||
|
<Arg><New class="org.eclipse.jetty.plus.jndi.NamingDump"/></Arg>
|
||||||
|
</Call>
|
||||||
|
|
||||||
</Configure>
|
</Configure>
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,15 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.plus.jndi;
|
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.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.empty;
|
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.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
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 TestNamingEntryUtil
|
||||||
{
|
{
|
||||||
public class MyNamingEntry extends NamingEntry
|
public class MyNamingEntry extends NamingEntry
|
||||||
|
@ -122,7 +121,7 @@ public class TestNamingEntryUtil
|
||||||
public void testLookupNamingEntries() throws Exception
|
public void testLookupNamingEntries() throws Exception
|
||||||
{
|
{
|
||||||
ScopeA scope = new ScopeA();
|
ScopeA scope = new ScopeA();
|
||||||
List<?> list = NamingEntryUtil.lookupNamingEntries(scope, MyNamingEntry.class);
|
List<? extends MyNamingEntry> list = NamingEntryUtil.lookupNamingEntries(scope, MyNamingEntry.class);
|
||||||
assertThat(list, is(empty()));
|
assertThat(list, is(empty()));
|
||||||
|
|
||||||
MyNamingEntry mne1 = new MyNamingEntry(scope, "a/b", 1);
|
MyNamingEntry mne1 = new MyNamingEntry(scope, "a/b", 1);
|
||||||
|
|
|
@ -18,6 +18,15 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.server;
|
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.io.EndPoint;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
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.Scheduler;
|
||||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
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
|
* @param maxConnections The maximum connections before low resources state is triggered
|
||||||
* @deprecated Replaced by ConnectionLimit
|
* @deprecated Replaced by {@link ConnectionLimit}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setMaxConnections(int maxConnections)
|
public void setMaxConnections(int maxConnections)
|
||||||
|
|
|
@ -28,7 +28,6 @@ import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
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.HandlerWrapper;
|
||||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||||
import org.eclipse.jetty.util.Attributes;
|
import org.eclipse.jetty.util.Attributes;
|
||||||
import org.eclipse.jetty.util.AttributesMap;
|
|
||||||
import org.eclipse.jetty.util.Jetty;
|
import org.eclipse.jetty.util.Jetty;
|
||||||
import org.eclipse.jetty.util.MultiException;
|
import org.eclipse.jetty.util.MultiException;
|
||||||
import org.eclipse.jetty.util.URIUtil;
|
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.ManagedAttribute;
|
||||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||||
import org.eclipse.jetty.util.annotation.Name;
|
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.component.LifeCycle;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
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 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 ThreadPool _threadPool;
|
||||||
private final List<Connector> _connectors = new CopyOnWriteArrayList<>();
|
private final List<Connector> _connectors = new CopyOnWriteArrayList<>();
|
||||||
private SessionIdManager _sessionIdManager;
|
private SessionIdManager _sessionIdManager;
|
||||||
|
@ -107,6 +106,7 @@ public class Server extends HandlerWrapper implements Attributes
|
||||||
ServerConnector connector=new ServerConnector(this);
|
ServerConnector connector=new ServerConnector(this);
|
||||||
connector.setPort(port);
|
connector.setPort(port);
|
||||||
setConnectors(new Connector[]{connector});
|
setConnectors(new Connector[]{connector});
|
||||||
|
addBean(_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -584,9 +584,6 @@ public class Server extends HandlerWrapper implements Attributes
|
||||||
@Override
|
@Override
|
||||||
public void clearAttributes()
|
public void clearAttributes()
|
||||||
{
|
{
|
||||||
Enumeration<String> names = _attributes.getAttributeNames();
|
|
||||||
while (names.hasMoreElements())
|
|
||||||
removeBean(_attributes.getAttribute(names.nextElement()));
|
|
||||||
_attributes.clearAttributes();
|
_attributes.clearAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,7 +604,7 @@ public class Server extends HandlerWrapper implements Attributes
|
||||||
@Override
|
@Override
|
||||||
public Enumeration<String> getAttributeNames()
|
public Enumeration<String> getAttributeNames()
|
||||||
{
|
{
|
||||||
return AttributesMap.getAttributeNamesCopy(_attributes);
|
return _attributes.getAttributeNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -617,9 +614,6 @@ public class Server extends HandlerWrapper implements Attributes
|
||||||
@Override
|
@Override
|
||||||
public void removeAttribute(String name)
|
public void removeAttribute(String name)
|
||||||
{
|
{
|
||||||
Object bean=_attributes.getAttribute(name);
|
|
||||||
if (bean!=null)
|
|
||||||
removeBean(bean);
|
|
||||||
_attributes.removeAttribute(name);
|
_attributes.removeAttribute(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,9 +624,6 @@ public class Server extends HandlerWrapper implements Attributes
|
||||||
@Override
|
@Override
|
||||||
public void setAttribute(String name, Object attribute)
|
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);
|
_attributes.setAttribute(name, attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,7 +684,7 @@ public class Server extends HandlerWrapper implements Attributes
|
||||||
@Override
|
@Override
|
||||||
public void dump(Appendable out,String indent) throws IOException
|
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;
|
_seconds = seconds;
|
||||||
_dateField = dateField;
|
_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
|
* @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
|
* @param <T> the Bean type
|
||||||
*/
|
*/
|
||||||
public <T> Collection<T> getContainedBeans(Class<T> clazz);
|
public <T> Collection<T> getContainedBeans(Class<T> clazz);
|
||||||
|
|
|
@ -550,13 +550,17 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
||||||
@Override
|
@Override
|
||||||
public <T> Collection<T> getBeans(Class<T> clazz)
|
public <T> Collection<T> getBeans(Class<T> clazz)
|
||||||
{
|
{
|
||||||
ArrayList<T> beans = new ArrayList<>();
|
ArrayList<T> beans = null;
|
||||||
for (Bean b : _beans)
|
for (Bean b : _beans)
|
||||||
{
|
{
|
||||||
if (clazz.isInstance(b._bean))
|
if (clazz.isInstance(b._bean))
|
||||||
|
{
|
||||||
|
if (beans == null)
|
||||||
|
beans = new ArrayList<>();
|
||||||
beans.add(clazz.cast(b._bean));
|
beans.add(clazz.cast(b._bean));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return beans;
|
return beans == null ? Collections.emptyList() : beans;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -879,7 +883,7 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param clazz the class of the beans
|
* @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
|
* @param <T> the Bean type
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@ -893,7 +897,7 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
||||||
/**
|
/**
|
||||||
* @param clazz the class of the beans
|
* @param clazz the class of the beans
|
||||||
* @param <T> the Bean type
|
* @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)
|
protected <T> void getContainedBeans(Class<T> clazz, Collection<T> beans)
|
||||||
{
|
{
|
||||||
|
|
|
@ -93,18 +93,19 @@ public interface Dumpable
|
||||||
String s;
|
String s;
|
||||||
if (o==null)
|
if (o==null)
|
||||||
s = "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)
|
else if (o instanceof Dumpable)
|
||||||
{
|
{
|
||||||
s = ((Dumpable)o).dumpSelf();
|
s = ((Dumpable)o).dumpSelf();
|
||||||
s = StringUtil.replace(s, "\r\n", "|");
|
s = StringUtil.replace(s, "\r\n", "|");
|
||||||
s = StringUtil.replace(s, '\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
|
else
|
||||||
{
|
{
|
||||||
s = String.valueOf(o);
|
s = String.valueOf(o);
|
||||||
|
@ -139,7 +140,7 @@ public interface Dumpable
|
||||||
{
|
{
|
||||||
dumpObject(out,object);
|
dumpObject(out,object);
|
||||||
|
|
||||||
int size = extraChildren==null?0:extraChildren.length;
|
int extras = extraChildren==null?0:extraChildren.length;
|
||||||
|
|
||||||
if (object instanceof Stream)
|
if (object instanceof Stream)
|
||||||
object = ((Stream)object).toArray();
|
object = ((Stream)object).toArray();
|
||||||
|
@ -148,87 +149,25 @@ public interface Dumpable
|
||||||
|
|
||||||
if (object instanceof Container)
|
if (object instanceof Container)
|
||||||
{
|
{
|
||||||
Container container = (Container)object;
|
dumpContainer(out, indent, (Container)object, extras==0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (object instanceof Iterable)
|
if (object instanceof Iterable)
|
||||||
{
|
{
|
||||||
for (Iterator i = ((Iterable<?>)object).iterator(); i.hasNext();)
|
dumpIterable(out, indent, (Iterable<?>)object, extras==0);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (object instanceof Map)
|
else if (object instanceof Map)
|
||||||
{
|
{
|
||||||
for (Iterator<? extends Map.Entry<?, ?>> i = ((Map<?,?>)object).entrySet().iterator(); i.hasNext();)
|
dumpMapEntries(out, indent, (Map<?,?>)object, extras==0);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size==0)
|
if (extras==0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Object item : extraChildren)
|
for (Object item : extraChildren)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
String nextIndent = indent + (i<size ? "| " : " ");
|
String nextIndent = indent + (i<extras ? "| " : " ");
|
||||||
out.append(indent).append("+> ");
|
out.append(indent).append("+> ");
|
||||||
if (item instanceof Dumpable)
|
if (item instanceof Dumpable)
|
||||||
((Dumpable)item).dump(out,nextIndent);
|
((Dumpable)item).dump(out,nextIndent);
|
||||||
|
@ -236,4 +175,91 @@ public interface Dumpable
|
||||||
dumpObjects(out, nextIndent, item);
|
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
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "WebAppClassLoader=" + _name+"@"+Long.toHexString(hashCode());
|
return String.format("%s{%s}@%x", this.getClass().getSimpleName(), _name, hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -34,7 +34,6 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletRegistration.Dynamic;
|
import javax.servlet.ServletRegistration.Dynamic;
|
||||||
import javax.servlet.ServletSecurityElement;
|
import javax.servlet.ServletSecurityElement;
|
||||||
|
@ -1040,15 +1039,10 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
if (_war!=null)
|
if (_war!=null)
|
||||||
{
|
return super.toString()+"{"+_war+"}";
|
||||||
String war=_war;
|
|
||||||
if (war.indexOf("/webapps/")>=0)
|
|
||||||
war=war.substring(war.indexOf("/webapps/")+8);
|
|
||||||
return super.toString()+"{"+war+"}";
|
|
||||||
}
|
|
||||||
return super.toString();
|
return super.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
@Override
|
@Override
|
||||||
public void dump(Appendable out, String indent) throws IOException
|
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);
|
server_classes=new ArrayList<>(_serverClasses);
|
||||||
Collections.sort(server_classes);
|
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,
|
dumpObjects(out,indent,
|
||||||
new ClassLoaderDump(getClassLoader()),
|
new ClassLoaderDump(getClassLoader()),
|
||||||
new DumpableCollection("Systemclasses "+this,system_classes),
|
new DumpableCollection("Systemclasses " + name, system_classes),
|
||||||
new DumpableCollection("Serverclasses "+this,server_classes),
|
new DumpableCollection("Serverclasses " + name, server_classes),
|
||||||
new DumpableCollection("Configurations "+this,_configurations),
|
new DumpableCollection("Configurations " + name, _configurations),
|
||||||
new DumpableCollection("Handler attributes "+this,((AttributesMap)getAttributes()).getAttributeEntrySet()),
|
new DumpableCollection("Handler attributes " + name, ((AttributesMap)getAttributes()).getAttributeEntrySet()),
|
||||||
new DumpableCollection("Context attributes "+this,((Context)getServletContext()).getAttributeEntrySet()),
|
new DumpableCollection("Context attributes " + name, ((Context)getServletContext()).getAttributeEntrySet()),
|
||||||
new DumpableCollection("Initparams "+this,getInitParams().entrySet())
|
new DumpableCollection("Initparams " + name, getInitParams().entrySet())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue