/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.web.tomcat.service.deployers;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executor;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.security.jacc.PolicyContext;
import javax.xml.namespace.QName;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Catalina;
import org.apache.catalina.startup.CatalinaProperties;
import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tomcat.util.modeler.Registry;
import org.jboss.bootstrap.spi.Server;
import org.jboss.kernel.spi.dependency.KernelController;
import org.jboss.kernel.spi.dependency.KernelControllerContext;
import org.jboss.security.plugins.JaasSecurityManagerServiceMBean;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.server.ServerImplMBean;
import org.jboss.util.StringPropertyReplacer;
import org.jboss.util.xml.JBossEntityResolver;
import org.jboss.web.tomcat.metadata.AnyXmlMetaData;
import org.jboss.web.tomcat.metadata.ConnectorMetaData;
import org.jboss.web.tomcat.metadata.EngineMetaData;
import org.jboss.web.tomcat.metadata.HostMetaData;
import org.jboss.web.tomcat.metadata.ListenerMetaData;
import org.jboss.web.tomcat.metadata.ServerMetaData;
import org.jboss.web.tomcat.metadata.ServiceMetaData;
import org.jboss.web.tomcat.metadata.ValveMetaData;
import org.jboss.web.tomcat.security.HttpServletRequestPolicyContextHandler;
import org.jboss.xb.binding.Unmarshaller;
import org.jboss.xb.binding.UnmarshallerFactory;
import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
import org.jboss.xb.builder.JBossXBBuilder;
/**
* Temporary workaround to support controlling the lifecycle of the webserver runtime portion of TomcatDeployer via a
* JMX service in the deploy directory. We want it in deploy so dependencies on services in deploy can be properly
* expressed. We want it as a JMX service so the ServiceBindingManager can alter the connector ports.
* <p>
* A more long term solution involves:
* <ol>
* <li>separating out the JBossWeb runtime aspects from TomcatDeployer and putting them in a separate class</li>
* <li>developing a ProfileService-based alternative to ServiceBindingManager</li>
* </ol>
* </p>
*
* @author <a href="brian.stansberry@jboss.com">Brian Stansberry</a>
* @version $Revision: 86387 $
*/
public class TomcatService extends ServiceMBeanSupport implements NotificationListener, TomcatServiceMBean
{
/** The associated Tomcat deployer * */
private TomcatDeployer tomcatDeployer;
/** The executor the Tomcat service should use * */
private Executor executor;
// Use a flag because isInShutdown doesn't appear to be correct
private boolean connectorsRunning = false;
// Dependency inject the Executor pojo
public Executor getExecutor()
{
return executor;
}
public void setExecutor(Executor executor)
{
this.executor = executor;
}
// Dependency inject the TomcatDeployer pojo
public TomcatDeployer getTomcatDeployer()
{
return tomcatDeployer;
}
public void setTomcatDeployer(TomcatDeployer tomcatDeployer)
{
this.tomcatDeployer = tomcatDeployer;
}
// In our lifecycle, we invoke the webserver lifecycle-related operations
// in the TomcatDeployer
@Override
protected void startService() throws Exception
{
if (tomcatDeployer == null)
throw new IllegalStateException("Must set TomcatDeployer before starting");
tomcatDeployer.setServiceClassLoader(getClass().getClassLoader());
// Load Catalina properties
CatalinaProperties.getProperty("");
log.debug("Starting tomcat deployer");
MBeanServer server = super.getServer();
SecurityActions.setSystemProperty("catalina.ext.dirs",
(SecurityActions.getSystemProperty("jboss.server.home.dir", null) + File.separator + "lib"));
String objectNameS = tomcatDeployer.getDomain() + ":type=Catalina";
ObjectName objectName = new ObjectName(objectNameS);
// Parse main server.xml
// FIXME: this could be done somewhere else
SchemaBinding schema = JBossXBBuilder.build(ServerMetaData.class);
Unmarshaller u = UnmarshallerFactory.newInstance().newUnmarshaller();
u.setSchemaValidation(false);
u.setValidation(false);
u.setEntityResolver(new JBossEntityResolver());
InputStream is = null;
ServerMetaData serverMetaData = null;
try {
File configFile = new File(tomcatDeployer.getConfigFile());
if (configFile.exists())
{
is = new FileInputStream(configFile);
}
else
{
is = getClass().getClassLoader().getResourceAsStream(tomcatDeployer.getConfigFile());
}
if (is == null) {
log.error("Could not read configured server.xml (will try default): " + tomcatDeployer.getConfigFile());
is = getClass().getClassLoader().getResourceAsStream("server.xml");
}
serverMetaData = ServerMetaData.class.cast(u.unmarshal(is, schema));
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// Ignore
}
}
}
// FIXME: could try to do stuff with EngineConfig and HostConfig, although neither
// should be useful in JBoss
// Create the Catalina instance
Catalina catalina = new Catalina();
catalina.setCatalinaHome(System.getProperty("jboss.server.home.dir"));
catalina.setUseNaming(false);
catalina.setUseShutdownHook(false);
catalina.setAwait(false);
catalina.setRedirectStreams(false);
// Set the modeler Registry MBeanServer to the that of the tomcat service
Registry.getRegistry(null, null).setMBeanServer(server);
// Register the Catalina instance
Registry.getRegistry(null, null).registerComponent(catalina, objectName, "org.apache.catalina.startup.Catalina");
// Use the server.xml metadata to create a Server instance and assign it to the Catalina instance
// Server
org.apache.catalina.Server catalinaServer =
(org.apache.catalina.Server) getInstance(serverMetaData, "org.apache.catalina.core.StandardServer");
Registry.getRegistry(null, null).registerComponent(catalinaServer,
new ObjectName(tomcatDeployer.getDomain() + ":type=Server"), "org.apache.catalina.startup.StandardServer");
addLifecycleListeners(catalinaServer, serverMetaData.getListeners());
// Server/Service
if (serverMetaData.getServices() == null)
{
throw new IllegalArgumentException("No services");
}
Iterator<ServiceMetaData> serviceMetaDatas = serverMetaData.getServices().iterator();
while (serviceMetaDatas.hasNext())
{
ServiceMetaData serviceMetaData = serviceMetaDatas.next();
org.apache.catalina.Service service =
(org.apache.catalina.Service) getInstance(serviceMetaData, "org.apache.catalina.core.StandardService");
addLifecycleListeners(service, serviceMetaData.getListeners());
service.setName(serviceMetaData.getName());
service.setServer(catalinaServer);
catalinaServer.addService(service);
// Server/Service/Executor
// Executor is useless in JBoss: the Executor will get injected in the executor field
// and used directly
// Server/Service/Connector
if (serviceMetaData.getConnectors() != null)
{
Iterator<ConnectorMetaData> connectorMetaDatas = serviceMetaData.getConnectors().iterator();
while (connectorMetaDatas.hasNext())
{
ConnectorMetaData connectorMetaData = connectorMetaDatas.next();
Connector connector = new Connector(connectorMetaData.getProtocol());
if (connectorMetaData.getAttributes() != null)
{
Iterator<QName> names = connectorMetaData.getAttributes().keySet().iterator();
while (names.hasNext())
{
QName name = names.next();
String value = (String) connectorMetaData.getAttributes().get(name);
// FIXME: This should be done by XB
value = StringPropertyReplacer.replaceProperties(value);
IntrospectionUtils.setProperty(connector, name.getLocalPart(), value);
}
}
if (executor != null)
{
IntrospectionUtils.callMethod1(connector.getProtocolHandler(), "setExecutor",
executor, java.util.concurrent.Executor.class.getName(), getClass().getClassLoader());
}
service.addConnector(connector);
}
}
// Server/Service/Engine
EngineMetaData engineMetaData = serviceMetaData.getEngine();
org.apache.catalina.Engine engine =
(org.apache.catalina.Engine) getInstance(engineMetaData, "org.apache.catalina.core.StandardEngine");
addLifecycleListeners(engine, engineMetaData.getListeners());
engine.setName(engineMetaData.getName());
// FIXME: This should be done by XB
if (engineMetaData.getJvmRoute() != null) {
engine.setJvmRoute(StringPropertyReplacer.replaceProperties(engineMetaData.getJvmRoute()));
}
//engine.setJvmRoute(engineMetaData.getJvmRoute());
engine.setDefaultHost(engineMetaData.getDefaultHost());
service.setContainer(engine);
// Server/Service/Engine/Realm
if (engineMetaData.getRealm() != null) {
engine.setRealm((org.apache.catalina.Realm) getInstance(engineMetaData.getRealm(), null));
}
// Server/Service/Engine/Valve
addValves(engine, engineMetaData.getValves());
// Server/Service/Engine/Host
if (engineMetaData.getHosts() != null)
{
Iterator<HostMetaData> hostMetaDatas = engineMetaData.getHosts().iterator();
while (hostMetaDatas.hasNext())
{
HostMetaData hostMetaData = hostMetaDatas.next();
org.apache.catalina.Host host =
(org.apache.catalina.Host) getInstance(hostMetaData, "org.apache.catalina.core.StandardHost");
addLifecycleListeners(host, hostMetaData.getListeners());
host.setName(hostMetaData.getName());
engine.addChild(host);
// Server/Service/Engine/Host/Realm
if (hostMetaData.getRealm() != null) {
host.setRealm((org.apache.catalina.Realm) getInstance(hostMetaData.getRealm(), null));
}
// Server/Service/Engine/Host/Valve
addValves(host, hostMetaData.getValves());
// Server/Service/Engine/Host/Alias
if (hostMetaData.getAliases() != null) {
Iterator<String> aliases = hostMetaData.getAliases().iterator();
while (aliases.hasNext()) {
host.addAlias(aliases.next());
}
}
}
}
}
// Set the resulting Server to the Catalina instance
catalina.setServer(catalinaServer);
// Start Tomcat
catalina.create();
catalinaServer.initialize();
catalina.start();
// Set up the authenticators in JNDI such that they can be configured for web apps
InitialContext ic = new InitialContext();
try
{
ic.bind("TomcatAuthenticators", tomcatDeployer.getAuthenticators());
}
catch (NamingException ne)
{
if (log.isTraceEnabled())
log.trace("Binding Authenticators to JNDI failed", ne);
}
finally
{
try
{
ic.close();
}
catch (NamingException nee)
{
}
}
// Register the web container JACC PolicyContextHandlers
HttpServletRequestPolicyContextHandler handler = new HttpServletRequestPolicyContextHandler();
PolicyContext.registerHandler(HttpServletRequestPolicyContextHandler.WEB_REQUEST_KEY, handler, true);
// If we are hot-deployed *after* the overall server is started
// we'll never receive Server.START_NOTIFICATION_TYPE, so check
// with the Server and start the connectors immediately, if this is the case.
// Otherwise register to receive the server start-up notification.
Boolean started = (Boolean) server.getAttribute(ServerImplMBean.OBJECT_NAME, "Started");
if (started.booleanValue() == true)
{
log.debug("Server '" + ServerImplMBean.OBJECT_NAME + "' already started, starting connectors now");
startConnectors();
}
else
{
// Register for notification of the overall server startup
log.debug("Server '" + ServerImplMBean.OBJECT_NAME + "' not started, registering for start-up notification");
server.addNotificationListener(ServerImplMBean.OBJECT_NAME, this, null, null);
}
}
/**
* Create a JavaBean corresponding to the given metadata, similar to what the digester is doing.
*/
protected static Object getInstance(AnyXmlMetaData metaData, String defaultClassName) throws Exception
{
String className = metaData.getClassName();
if (className == null) {
className = defaultClassName;
}
if (className == null) {
throw new IllegalArgumentException("No className specified for element");
}
Object instance = TomcatService.class.getClassLoader().loadClass(className).newInstance();
if (metaData.getAttributes() != null) {
Iterator<QName> names = metaData.getAttributes().keySet().iterator();
while (names.hasNext()) {
QName name = names.next();
String value = (String) metaData.getAttributes().get(name);
// FIXME: This should be done by XB
value = StringPropertyReplacer.replaceProperties(value);
IntrospectionUtils.setProperty(instance, name.getLocalPart(), value);
}
}
return instance;
}
/**
* Associate lifecycle listeners with the instance, if it implements Lifecycle.
*/
protected static void addLifecycleListeners(Object instance, List<ListenerMetaData> list) throws Exception
{
if (list == null) {
return;
}
org.apache.catalina.Lifecycle lifecycle = null;
if (!(instance instanceof org.apache.catalina.Lifecycle))
{
return;
}
else
{
lifecycle = (org.apache.catalina.Lifecycle) instance;
}
Iterator<ListenerMetaData> listenerMetaDatas = list.iterator();
while (listenerMetaDatas.hasNext())
{
ListenerMetaData listenerMetaData = listenerMetaDatas.next();
lifecycle.addLifecycleListener((org.apache.catalina.LifecycleListener) getInstance(listenerMetaData, null));
}
}
/**
* Associate valves with the instance, if it implements Lifecycle.
*/
protected static void addValves(Object instance, List<ValveMetaData> list) throws Exception
{
if (list == null) {
return;
}
org.apache.catalina.Pipeline pipeline = null;
if (!(instance instanceof org.apache.catalina.Pipeline))
{
return;
}
else
{
pipeline = (org.apache.catalina.Pipeline) instance;
}
Iterator<ValveMetaData> valveMetaDatas = list.iterator();
while (valveMetaDatas.hasNext())
{
ValveMetaData valveMetaData = valveMetaDatas.next();
pipeline.addValve((org.apache.catalina.Valve) getInstance(valveMetaData, null));
}
}
@Override
protected void stopService() throws Exception
{
if (tomcatDeployer == null)
throw new IllegalStateException("Must set TomcatDeployer before stopping");
// Hot undeploy
Boolean inShutdown = (Boolean) server.getAttribute(ServerImplMBean.OBJECT_NAME, "InShutdown");
if (inShutdown.booleanValue() == false)
{
log.debug("Server '" + ServerImplMBean.OBJECT_NAME + "' already started, stopping connectors now");
stopConnectors();
}
MBeanServer server = super.getServer();
String objectNameS = tomcatDeployer.getDomain() + ":type=Catalina";
ObjectName objectName = new ObjectName(objectNameS);
server.invoke(objectName, "stop", new Object[]{}, new String[]{});
server.invoke(objectName, "destroy", new Object[]{}, new String[]{});
server.unregisterMBean(objectName);
MBeanServer server2 = server;
// Unregister any remaining jboss.web or Catalina MBeans
ObjectName queryObjectName = new ObjectName(tomcatDeployer.getDomain() + ":*");
Iterator iterator = server2.queryMBeans(queryObjectName, null).iterator();
while (iterator.hasNext())
{
ObjectInstance oi = (ObjectInstance) iterator.next();
ObjectName toRemove = oi.getObjectName();
// Exception: Don't unregister the service right now
if (!"WebServer".equals(toRemove.getKeyProperty("service")))
{
if (server2.isRegistered(toRemove))
{
server2.unregisterMBean(toRemove);
}
}
}
}
// Expose the TomcatDeployer MBean interface
public String getConfigFile()
{
return tomcatDeployer == null ? null : tomcatDeployer.getConfigFile();
}
public String getContextMBeanCode()
{
return tomcatDeployer == null ? null : tomcatDeployer.getContextMBeanCode();
}
public boolean getUseJBossWebLoader()
{
return tomcatDeployer == null ? false : tomcatDeployer.getUseJBossWebLoader();
}
public String getDomain()
{
return tomcatDeployer == null ? null : tomcatDeployer.getDomain();
}
public String[] getFilteredPackages()
{
return tomcatDeployer == null ? null : tomcatDeployer.getFilteredPackages();
}
public String getManagerClass()
{
return tomcatDeployer == null ? null : tomcatDeployer.getManagerClass();
}
public String getSessionIdAlphabet()
{
return tomcatDeployer == null ? null : tomcatDeployer.getSessionIdAlphabet();
}
public String getSubjectAttributeName()
{
return tomcatDeployer == null ? null : tomcatDeployer.getSubjectAttributeName();
}
public boolean getDeleteWorkDirOnContextDestroy()
{
return tomcatDeployer == null ? false : tomcatDeployer.getDeleteWorkDirOnContextDestroy();
}
public boolean isAllowSelfPrivilegedWebApps()
{
return tomcatDeployer == null ? false : tomcatDeployer.isAllowSelfPrivilegedWebApps();
}
public void setAllowSelfPrivilegedWebApps(boolean flag)
{
if (tomcatDeployer != null)
tomcatDeployer.setAllowSelfPrivilegedWebApps(flag);
}
public void setConfigFile(String configFile)
{
if (tomcatDeployer != null)
tomcatDeployer.setConfigFile(configFile);
}
public void setContextMBeanCode(String className)
{
if (tomcatDeployer != null)
tomcatDeployer.setContextMBeanCode(className);
}
public void setDeleteWorkDirOnContextDestroy(boolean flag)
{
if (tomcatDeployer != null)
tomcatDeployer.setDeleteWorkDirOnContextDestroy(flag);
}
public void setDomain(String domainName)
{
if (tomcatDeployer != null)
tomcatDeployer.setDomain(domainName);
}
public void setFilteredPackages(String[] pkgs)
{
if (tomcatDeployer != null)
tomcatDeployer.setFilteredPackages(pkgs);
}
public void setManagerClass(String managerClass)
{
if (tomcatDeployer != null)
tomcatDeployer.setManagerClass(managerClass);
}
public void setSecurityManagerService(JaasSecurityManagerServiceMBean mgr)
{
if (tomcatDeployer != null)
tomcatDeployer.setSecurityManagerService(mgr);
}
public void setSessionIdAlphabet(String sessionIdAlphabet)
{
if (tomcatDeployer != null)
tomcatDeployer.setSessionIdAlphabet(sessionIdAlphabet);
}
public void setSubjectAttributeName(String name)
{
if (tomcatDeployer != null)
tomcatDeployer.setSubjectAttributeName(name);
}
public void setUseJBossWebLoader(boolean flag)
{
if (tomcatDeployer != null)
tomcatDeployer.setUseJBossWebLoader(flag);
}
public void startConnectors() throws Exception
{
if (tomcatDeployer == null)
throw new IllegalStateException("Must set TomcatDeployer before starting connectors");
if (connectorsRunning)
return;
MBeanServer server = super.getServer();
ObjectName service = new ObjectName(tomcatDeployer.getDomain() + ":type=Service,serviceName=jboss.web");
Object[] args = {};
String[] sig = {};
Connector[] connectors = (Connector[]) server.invoke(service, "findConnectors", args, sig);
for (int n = 0; n < connectors.length; n++)
{
Lifecycle lc = connectors[n];
lc.start();
}
/*
* TODO: // Notify listeners that connectors have started processing requests sendNotification(new
* Notification(TOMCAT_CONNECTORS_STARTED, this, getNextNotificationSequenceNumber()));
*/
connectorsRunning = true;
}
public void stopConnectors() throws Exception
{
if (tomcatDeployer == null)
throw new IllegalStateException("Must set TomcatDeployer before stopping connectors");
if (!connectorsRunning)
return;
MBeanServer server = super.getServer();
ObjectName service = new ObjectName(tomcatDeployer.getDomain() + ":type=Service,serviceName=jboss.web");
Object[] args = {};
String[] sig = {};
Connector[] connectors = (Connector[]) server.invoke(service, "findConnectors", args, sig);
for (int n = 0; n < connectors.length; n++)
{
connectors[n].pause();
connectors[n].stop();
}
connectorsRunning = false;
}
/**
* Used to receive notification of the server start msg so the tomcat connectors can be started after all web apps
* are deployed.
*/
public void handleNotification(Notification msg, Object handback)
{
String type = msg.getType();
if (type.equals(Server.START_NOTIFICATION_TYPE))
{
log.debug("Saw " + type + " notification, starting connectors");
try
{
startConnectors();
}
catch (Exception e)
{
log.warn("Failed to startConnectors", e);
}
}
if (type.equals(Server.STOP_NOTIFICATION_TYPE))
{
log.debug("Saw " + type + " notification, stopping connectors");
try
{
stopConnectors();
}
catch (Exception e)
{
log.warn("Failed to stopConnectors", e);
}
}
}
public String getDefaultSecurityDomain()
{
return tomcatDeployer == null ? null : tomcatDeployer.getDefaultSecurityDomain();
}
public boolean getJava2ClassLoadingCompliance()
{
return tomcatDeployer == null ? false : tomcatDeployer.getJava2ClassLoadingCompliance();
}
public boolean getLenientEjbLink()
{
return tomcatDeployer == null ? false : tomcatDeployer.getLenientEjbLink();
}
public boolean getUnpackWars()
{
return tomcatDeployer == null ? false : tomcatDeployer.getUnpackWars();
}
public void setDefaultSecurityDomain(String defaultSecurityDomain)
{
if (tomcatDeployer != null)
tomcatDeployer.setDefaultSecurityDomain(defaultSecurityDomain);
}
public void setJava2ClassLoadingCompliance(boolean flag)
{
if (tomcatDeployer != null)
tomcatDeployer.setJava2ClassLoadingCompliance(flag);
}
public void setLenientEjbLink(boolean flag)
{
if (tomcatDeployer != null)
tomcatDeployer.setLenientEjbLink(flag);
}
public void setUnpackWars(boolean flag)
{
if (tomcatDeployer != null)
tomcatDeployer.setUnpackWars(flag);
}
/*
* (non-Javadoc)
*
* @see org.jboss.web.tomcat.service.deployers.TomcatDeployerMBean#getHttpHeaderForSSOAuth()
*/
public String getHttpHeaderForSSOAuth()
{
return tomcatDeployer == null ? null : tomcatDeployer.getHttpHeaderForSSOAuth();
}
/*
* (non-Javadoc)
*
* @see org.jboss.web.tomcat.service.deployers.TomcatDeployerMBean#setHttpHeaderForSSOAuth(java.lang.String)
*/
public void setHttpHeaderForSSOAuth(String httpHeaderForSSOAuth)
{
if (this.tomcatDeployer != null)
this.tomcatDeployer.setHttpHeaderForSSOAuth(httpHeaderForSSOAuth);
}
/*
* (non-Javadoc)
*
* @see org.jboss.web.tomcat.service.deployers.TomcatDeployerMBean#getSessionCookieForSSOAuth()
*/
public String getSessionCookieForSSOAuth()
{
return tomcatDeployer == null ? null : tomcatDeployer.getSessionCookieForSSOAuth();
}
/*
* (non-Javadoc)
*
* @see org.jboss.web.tomcat.service.deployers.TomcatDeployerMBean#setSessionCookieForSSOAuth(java.lang.String)
*/
public void setSessionCookieForSSOAuth(String sessionCookieForSSOAuth)
{
if (this.tomcatDeployer != null)
this.tomcatDeployer.setSessionCookieForSSOAuth(sessionCookieForSSOAuth);
}
/**
* {@inheritDoc}
*
* Overrides the superclass version to inject the <code>KernelController</code>
* into {@link JBossWebMicrocontainerBeanLocator}.
*/
@Override
public void setKernelControllerContext(KernelControllerContext controllerContext) throws Exception
{
super.setKernelControllerContext(controllerContext);
KernelController kernelController = controllerContext == null ? null : controllerContext.getKernel().getController();
JBossWebMicrocontainerBeanLocator.setKernelController(kernelController);
}
/**
* {@inheritDoc}
*
* Overrides the superclass version to clear the <code>KernelController</code>
* from {@link JBossWebMicrocontainerBeanLocator}.
*/
@Override
public void unsetKernelControllerContext(KernelControllerContext controllerContext) throws Exception
{
super.unsetKernelControllerContext(controllerContext);
JBossWebMicrocontainerBeanLocator.setKernelController(null);
}
}