下面列出了org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer#org.apache.catalina.Container 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Create a new JNDI Realm.
*
* @param parent MBean Name of the associated parent component
* @return the object name of the created realm
*
* @exception Exception if an MBean cannot be created or registered
*/
public String createJNDIRealm(String parent) throws Exception {
// Create a new JNDIRealm instance
JNDIRealm realm = new JNDIRealm();
// Add the new instance to its parent component
ObjectName pname = new ObjectName(parent);
Container container = getParentContainerFromParent(pname);
// Add the new instance to its parent component
container.setRealm(realm);
// Return the corresponding MBean name
ObjectName oname = realm.getObjectName();
if (oname != null) {
return (oname.toString());
} else {
return null;
}
}
@Test
void it_should_add_parent_classloader(@TempDir File tmpDir) throws Exception {
final File tmpFile = Files.createTempFile(tmpDir.toPath(), null, null).toFile();
final File dir = tmpFile.getParentFile();
tomcat = new EmbeddedTomcat(EmbeddedTomcatConfiguration.builder()
.withWebapp(dir)
.withParentClasspath(dir.toURI().toURL())
.build());
tomcat.start();
final Container[] containers = tomcat.getDelegate().getHost().findChildren();
final ClassLoader cl = containers[0].getParentClassLoader();
assertThat(cl).isNotNull();
assertThat(cl.getResource("hello-world.html")).isNotNull();
assertThat(cl.getResource(tmpFile.getName())).isNotNull();
}
/**
* Determine the name of the domain to register MBeans for from a given
* Container.
*
* @param container
*
* @deprecated To be removed since to creates a circular dependency. Will
* be replaced in Tomcat 8 by a new method on {@link
* Container}.
*/
@Deprecated
public static String getDomain(Container container) {
String domain = null;
Container c = container;
while (!(c instanceof Engine) && c != null) {
c = c.getParent();
}
if (c != null) {
domain = c.getName();
}
return domain;
}
/**
* Handle the beginning of an XML element.
*
* @param attributes The attributes of this element
*
* @exception Exception if a processing error occurs
*/
@Override
public void begin(String namespace, String name, Attributes attributes)
throws Exception {
if (digester.getLogger().isDebugEnabled())
digester.getLogger().debug("Copying parent class loader");
Container child = (Container) digester.peek(0);
Object parent = digester.peek(1);
Method method =
parent.getClass().getMethod("getParentClassLoader", new Class[0]);
ClassLoader classLoader =
(ClassLoader) method.invoke(parent, new Object[0]);
child.setParentClassLoader(classLoader);
}
/**
* Handle the beginning of an XML element.
*
* @param attributes The attributes of this element
*
* @exception Exception if a processing error occurs
*/
@Override
public void begin(String namespace, String name, Attributes attributes)
throws Exception {
if (digester.getLogger().isDebugEnabled())
digester.getLogger().debug("Copying parent class loader");
Container child = (Container) digester.peek(0);
Object parent = digester.peek(1);
Method method =
parent.getClass().getMethod("getParentClassLoader", new Class[0]);
ClassLoader classLoader =
(ClassLoader) method.invoke(parent, new Object[0]);
child.setParentClassLoader(classLoader);
}
/**
* Determine the name of the domain to register MBeans for from a given
* Service.
*
* @param service
*
* @deprecated To be removed since to creates a circular dependency. Will
* be replaced in Tomcat 8 by a new method on {@link
* Service}.
*/
@Deprecated
public static String getDomain(Service service) {
// Null service -> return null
if (service == null) {
return null;
}
String domain = null;
Container engine = service.getContainer();
// Use the engine name first
if (engine != null) {
domain = engine.getName();
}
// No engine or no engine name, use the service name
if (domain == null) {
domain = service.getName();
}
// No service name, use null
return domain;
}
@Override
public void containerEvent(ContainerEvent event) {
try {
String type = event.getType();
if (Container.ADD_CHILD_EVENT.equals(type)) {
processContainerAddChild(event.getContainer(),
(Container) event.getData());
} else if (Container.REMOVE_CHILD_EVENT.equals(type)) {
processContainerRemoveChild(event.getContainer(),
(Container) event.getData());
}
} catch (Exception e) {
String msg =
sm.getString(
"threadLocalLeakPreventionListener.containerEvent.error",
event);
log.error(msg, e);
}
}
/**
* Create a new DataSource Realm.
*
* @param parent MBean Name of the associated parent component
* @param dataSourceName the datasource name
* @param roleNameCol the column name for the role names
* @param userCredCol the column name for the user credentials
* @param userNameCol the column name for the user names
* @param userRoleTable the table name for the roles table
* @param userTable the table name for the users
* @return the object name of the created realm
* @exception Exception if an MBean cannot be created or registered
*/
public String createDataSourceRealm(String parent, String dataSourceName,
String roleNameCol, String userCredCol, String userNameCol,
String userRoleTable, String userTable) throws Exception {
// Create a new DataSourceRealm instance
DataSourceRealm realm = new DataSourceRealm();
realm.setDataSourceName(dataSourceName);
realm.setRoleNameCol(roleNameCol);
realm.setUserCredCol(userCredCol);
realm.setUserNameCol(userNameCol);
realm.setUserRoleTable(userRoleTable);
realm.setUserTable(userTable);
// Add the new instance to its parent component
ObjectName pname = new ObjectName(parent);
Container container = getParentContainerFromParent(pname);
// Add the new instance to its parent component
container.setRealm(realm);
// Return the corresponding MBean name
ObjectName oname = realm.getObjectName();
if (oname != null) {
return oname.toString();
} else {
return null;
}
}
/**
* Create a new StandardManager.
*
* @param parent MBean Name of the associated parent component
* @return the object name of the created manager
*
* @exception Exception if an MBean cannot be created or registered
*/
public String createStandardManager(String parent)
throws Exception {
// Create a new StandardManager instance
StandardManager manager = new StandardManager();
// Add the new instance to its parent component
ObjectName pname = new ObjectName(parent);
Container container = getParentContainerFromParent(pname);
if (container instanceof Context) {
((Context) container).setManager(manager);
} else {
throw new Exception(sm.getString("mBeanFactory.managerContext"));
}
ObjectName oname = manager.getObjectName();
if (oname != null) {
return oname.toString();
} else {
return null;
}
}
/**
* Create a new Web Application Loader.
*
* @param parent MBean Name of the associated parent component
* @return the object name of the created loader
*
* @exception Exception if an MBean cannot be created or registered
*/
public String createWebappLoader(String parent)
throws Exception {
// Create a new WebappLoader instance
WebappLoader loader = new WebappLoader();
// Add the new instance to its parent component
ObjectName pname = new ObjectName(parent);
Container container = getParentContainerFromParent(pname);
if (container instanceof Context) {
((Context) container).setLoader(loader);
}
// FIXME add Loader.getObjectName
//ObjectName oname = loader.getObjectName();
ObjectName oname =
MBeanUtils.createObjectName(pname.getDomain(), loader);
return oname.toString();
}
/**
* Register host.
*/
private void registerHost(Host host) {
String[] aliases = host.findAliases();
mapper.addHost(host.getName(), aliases, host);
for (Container container : host.findChildren()) {
if (container.getState().isAvailable()) {
registerContext((Context) container);
}
}
if(log.isDebugEnabled()) {
log.debug(sm.getString("mapperListener.registerHost",
host.getName(), domain, connector));
}
}
/**
* Find the configuration path where the rewrite configuration file
* will be stored.
* @param resourceName The rewrite configuration file name
* @return the full rewrite configuration path
*/
protected String getHostConfigPath(String resourceName) {
StringBuffer result = new StringBuffer();
Container container = getContainer();
Container host = null;
Container engine = null;
while (container != null) {
if (container instanceof Host)
host = container;
if (container instanceof Engine)
engine = container;
container = container.getParent();
}
if (engine != null) {
result.append(engine.getName()).append('/');
}
if (host != null) {
result.append(host.getName()).append('/');
}
result.append(resourceName);
return result.toString();
}
/**
* Add a child Container, only if the proposed child is an implementation
* of Context.
*
* @param child Child container to be added
*/
@Override
public void addChild(Container child) {
if (!(child instanceof Context))
throw new IllegalArgumentException
(sm.getString("standardHost.notContext"));
child.addLifecycleListener(new MemoryLeakTrackingListener());
// Avoid NPE for case where Context is defined in server.xml with only a
// docBase
Context context = (Context) child;
if (context.getPath() == null) {
ContextName cn = new ContextName(context.getDocBase(), true);
context.setPath(cn.getPath());
}
super.addChild(child);
}
/**
* Render a list of the currently active Contexts in our virtual host.
*
* @param writer Writer to render to
*/
protected void list(PrintWriter writer, StringManager smClient) {
if (debug >= 1) {
log(sm.getString("hostManagerServlet.list", engine.getName()));
}
writer.println(smClient.getString("hostManagerServlet.listed",
engine.getName()));
Container[] hosts = engine.findChildren();
for (int i = 0; i < hosts.length; i++) {
Host host = (Host) hosts[i];
String name = host.getName();
String[] aliases = host.findAliases();
StringBuilder buf = new StringBuilder();
if (aliases.length > 0) {
buf.append(aliases[0]);
for (int j = 1; j < aliases.length; j++) {
buf.append(',').append(aliases[j]);
}
}
writer.println(smClient.getString("hostManagerServlet.listitem",
name, buf.toString()));
}
}
/**
* Create a new Valve and associate it with a {@link Container}.
*
* @param className The fully qualified class name of the {@link Valve} to
* create
* @param parent The MBean name of the associated parent
* {@link Container}.
*
* @return The MBean name of the {@link Valve} that was created or
* <code>null</code> if the {@link Valve} does not implement
* {@link LifecycleMBeanBase}.
*/
public String createValve(String className, String parent)
throws Exception {
// Look for the parent
ObjectName parentName = new ObjectName(parent);
Container container = getParentContainerFromParent(parentName);
if (container == null) {
// TODO
throw new IllegalArgumentException();
}
Valve valve = (Valve) Class.forName(className).newInstance();
container.getPipeline().addValve(valve);
if (valve instanceof LifecycleMBeanBase) {
return ((LifecycleMBeanBase) valve).getObjectName().toString();
} else {
return null;
}
}
/**
* Deregister the MBean for this
* <code>Valve</code> object.
*
* @param valve The Valve to be managed
*
* @exception Exception if an MBean cannot be deregistered
* @deprecated Unused. Will be removed in Tomcat 8.0.x
*/
@Deprecated
static void destroyMBean(Valve valve, Container container)
throws Exception {
((Contained)valve).setContainer(container);
String mname = createManagedName(valve);
ManagedBean managed = registry.findManagedBean(mname);
if (managed == null) {
return;
}
String domain = managed.getDomain();
if (domain == null)
domain = mserver.getDefaultDomain();
ObjectName oname = createObjectName(domain, valve);
try {
((Contained)valve).setContainer(null);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
}
if( mserver.isRegistered(oname) ) {
mserver.unregisterMBean(oname);
}
}
/**
* Deregister the MBean for this
* <code>Valve</code> object.
*
* @param valve The Valve to be managed
*
* @exception Exception if an MBean cannot be deregistered
* @deprecated Unused. Will be removed in Tomcat 8.0.x
*/
@Deprecated
static void destroyMBean(Valve valve, Container container)
throws Exception {
((Contained)valve).setContainer(container);
String mname = createManagedName(valve);
ManagedBean managed = registry.findManagedBean(mname);
if (managed == null) {
return;
}
String domain = managed.getDomain();
if (domain == null)
domain = mserver.getDefaultDomain();
ObjectName oname = createObjectName(domain, valve);
try {
((Contained)valve).setContainer(null);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
}
if( mserver.isRegistered(oname) ) {
mserver.unregisterMBean(oname);
}
}
/**
* Add this mapper to the container and all child containers
*
* @param container
*/
private void addListeners(Container container) {
container.addContainerListener(this);
container.addLifecycleListener(this);
for (Container child : container.findChildren()) {
addListeners(child);
}
}
private Context findContext() {
for (Container child : this.tomcat.getHost().findChildren()) {
if (child instanceof Context) {
if (child.getParentClassLoader().equals(
Thread.currentThread().getContextClassLoader())) {
return (Context) child;
}
}
}
throw new IllegalStateException("The host does not contain a Context");
}
@Override
public int getMaxInactiveInterval() {
Container container = getContainer();
if (container instanceof Context) {
// This method returns seconds, the Context uses minutes
return ((Context) container).getSessionTimeout() * 60;
}
return -1;
}
private void expire(SingleSignOnSessionKey key) {
if (engine == null) {
containerLog.warn(sm.getString("singleSignOn.sessionExpire.engineNull", key));
return;
}
Container host = engine.findChild(key.getHostName());
if (host == null) {
containerLog.warn(sm.getString("singleSignOn.sessionExpire.hostNotFound", key));
return;
}
Context context = (Context) host.findChild(key.getContextName());
if (context == null) {
containerLog.warn(sm.getString("singleSignOn.sessionExpire.contextNotFound", key));
return;
}
Manager manager = context.getManager();
if (manager == null) {
containerLog.warn(sm.getString("singleSignOn.sessionExpire.managerNotFound", key));
return;
}
Session session = null;
try {
session = manager.findSession(key.getSessionId());
} catch (IOException e) {
containerLog.warn(sm.getString("singleSignOn.sessionExpire.managerError", key), e);
return;
}
if (session == null) {
containerLog.warn(sm.getString("singleSignOn.sessionExpire.sessionNotFound", key));
return;
}
session.expire();
}
private void rethrowDeferredStartupExceptions() throws Exception {
Container[] children = this.tomcat.getHost().findChildren();
for (Container container : children) {
if (!LifecycleState.STARTED.equals(container.getState())) {
throw new IllegalStateException(container + " failed to start");
}
}
}
@Override
public String getServiceName() {
if (resources != null) {
Container host = resources.getContext().getParent();
if (host != null) {
Container engine = host.getParent();
if (engine != null) {
return engine.getName();
}
}
}
return null;
}
@Override
public Map<String, ? extends ServletRegistration> getServletRegistrations() {
Map<String, ApplicationServletRegistration> result =
new HashMap<String, ApplicationServletRegistration>();
Container[] wrappers = context.findChildren();
for (Container wrapper : wrappers) {
result.put(((Wrapper) wrapper).getName(),
new ApplicationServletRegistration(
(Wrapper) wrapper, context));
}
return result;
}
/**
* <p>Add a new Valve to the end of the pipeline associated with this
* Container. Prior to adding the Valve, the Valve's
* <code>setContainer()</code> method will be called, if it implements
* <code>Contained</code>, with the owning Container as an argument.
* The method may throw an
* <code>IllegalArgumentException</code> if this Valve chooses not to
* be associated with this Container, or <code>IllegalStateException</code>
* if it is already associated with a different Container.</p>
*
* @param valve Valve to be added
*
* @exception IllegalArgumentException if this Container refused to
* accept the specified Valve
* @exception IllegalArgumentException if the specified Valve refuses to be
* associated with this Container
* @exception IllegalStateException if the specified Valve is already
* associated with a different Container
*/
@Override
public void addValve(Valve valve) {
// Validate that we can add this Valve
if (valve instanceof Contained)
((Contained) valve).setContainer(this.container);
// Start the new component if necessary
if (getState().isAvailable()) {
if (valve instanceof Lifecycle) {
try {
((Lifecycle) valve).start();
} catch (LifecycleException e) {
log.error("StandardPipeline.addValve: start: ", e);
}
}
}
// Add this Valve to the set associated with this Pipeline
if (first == null) {
first = valve;
valve.setNext(basic);
} else {
Valve current = first;
while (current != null) {
if (current.getNext() == basic) {
current.setNext(valve);
valve.setNext(basic);
break;
}
current = current.getNext();
}
}
container.fireContainerEvent(Container.ADD_VALVE_EVENT, valve);
}
/**
* Remove this mapper from the container and all child containers
*
* @param container
*/
private void removeListeners(Container container) {
container.removeContainerListener(this);
container.removeLifecycleListener(this);
for (Container child : container.findChildren()) {
removeListeners(child);
}
}
@Override
public void setContainer(Container container) {
super.setContainer(container);
if (container instanceof Engine || container instanceof Host) {
clBindRequired = true;
} else {
clBindRequired = false;
}
}
@Override
protected String getDomainInternal() {
Container p = getParent();
if (p == null) {
return null;
} else {
return p.getDomain();
}
}
/**
* Process running web applications for ejb deployments.
*
* @param tomcatWebAppBuilder tomcat web app builder instance
* @param standardServer tomcat server instance
*/
private void processRunningApplications(final TomcatWebAppBuilder tomcatWebAppBuilder, final StandardServer standardServer) {
for (final org.apache.catalina.Service service : standardServer.findServices()) {
if (service.getContainer() instanceof Engine) {
final Engine engine = (Engine) service.getContainer();
for (final Container engineChild : engine.findChildren()) {
if (engineChild instanceof Host) {
final Host host = (Host) engineChild;
for (final Container hostChild : host.findChildren()) {
if (hostChild instanceof StandardContext) {
final StandardContext standardContext = (StandardContext) hostChild;
final int state = TomcatHelper.getContextState(standardContext);
if (state == 0) {
// context only initialized
tomcatWebAppBuilder.init(standardContext);
} else if (state == 1) {
// context already started
standardContext.addParameter("openejb.start.late", "true");
final ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(standardContext.getLoader().getClassLoader());
try {
tomcatWebAppBuilder.init(standardContext);
tomcatWebAppBuilder.beforeStart(standardContext);
tomcatWebAppBuilder.start(standardContext);
tomcatWebAppBuilder.afterStart(standardContext);
} finally {
Thread.currentThread().setContextClassLoader(oldCL);
}
standardContext.removeParameter("openejb.start.late");
}
}
}
}
}
}
}
}
/**
* Start this component and implement the requirements
* of {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
@Override
protected synchronized void startInternal() throws LifecycleException {
// Look up the SingleSignOn implementation in our request processing
// path, if there is one
Container parent = context.getParent();
while ((sso == null) && (parent != null)) {
Valve valves[] = parent.getPipeline().getValves();
for (int i = 0; i < valves.length; i++) {
if (valves[i] instanceof SingleSignOn) {
sso = (SingleSignOn) valves[i];
break;
}
}
if (sso == null)
parent = parent.getParent();
}
if (log.isDebugEnabled()) {
if (sso != null)
log.debug("Found SingleSignOn Valve at " + sso);
else
log.debug("No SingleSignOn Valve is present");
}
sessionIdGenerator = new StandardSessionIdGenerator();
sessionIdGenerator.setSecureRandomAlgorithm(getSecureRandomAlgorithm());
sessionIdGenerator.setSecureRandomClass(getSecureRandomClass());
sessionIdGenerator.setSecureRandomProvider(getSecureRandomProvider());
super.startInternal();
}