Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » mbeans » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.catalina.mbeans;
   19   
   20   
   21   import java.beans.PropertyChangeEvent;
   22   import java.beans.PropertyChangeListener;
   23   import javax.management.MBeanException;
   24   
   25   import org.apache.catalina.Container;
   26   import org.apache.catalina.ContainerEvent;
   27   import org.apache.catalina.ContainerListener;
   28   import org.apache.catalina.Context;
   29   import org.apache.catalina.Engine;
   30   import org.apache.catalina.Globals;
   31   import org.apache.catalina.Host;
   32   import org.apache.catalina.Lifecycle;
   33   import org.apache.catalina.LifecycleEvent;
   34   import org.apache.catalina.LifecycleListener;
   35   import org.apache.catalina.Loader;
   36   import org.apache.catalina.Manager;
   37   import org.apache.catalina.Realm;
   38   import org.apache.catalina.Server;
   39   import org.apache.catalina.ServerFactory;
   40   import org.apache.catalina.Service;
   41   import org.apache.catalina.connector.Connector;
   42   import org.apache.catalina.core.StandardContext;
   43   import org.apache.catalina.core.StandardEngine;
   44   import org.apache.catalina.core.StandardHost;
   45   import org.apache.catalina.core.StandardServer;
   46   import org.apache.catalina.core.StandardService;
   47   import org.apache.catalina.deploy.ContextEnvironment;
   48   import org.apache.catalina.deploy.ContextResource;
   49   import org.apache.catalina.deploy.ContextResourceLink;
   50   import org.apache.catalina.deploy.NamingResources;
   51   import org.apache.juli.logging.Log;
   52   import org.apache.juli.logging.LogFactory;
   53   
   54   
   55   /**
   56    * Implementation of <code>LifecycleListener</code> that
   57    * instantiates the set of MBeans associated with the components of a
   58    * running instance of Catalina.
   59    *
   60    * @author Craig R. McClanahan
   61    * @author Amy Roh
   62    * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
   63    */
   64   
   65   public class ServerLifecycleListener
   66       implements ContainerListener, LifecycleListener, PropertyChangeListener {
   67   
   68       private static Log log = LogFactory.getLog(ServerLifecycleListener.class);
   69   
   70   
   71       // ------------------------------------------------------------- Properties
   72   
   73   
   74       /**
   75        * Semicolon separated list of paths containing MBean desciptor resources.
   76        */
   77       protected String descriptors = null;
   78   
   79       public String getDescriptors() {
   80           return (this.descriptors);
   81       }
   82   
   83       public void setDescriptors(String descriptors) {
   84           this.descriptors = descriptors;
   85       }
   86   
   87   
   88       // ---------------------------------------------- ContainerListener Methods
   89   
   90   
   91       /**
   92        * Handle a <code>ContainerEvent</code> from one of the Containers we are
   93        * interested in.
   94        *
   95        * @param event The event that has occurred
   96        */
   97       public void containerEvent(ContainerEvent event) {
   98   
   99           try {
  100               String type = event.getType();
  101               if (Container.ADD_CHILD_EVENT.equals(type)) {
  102                   processContainerAddChild(event.getContainer(),
  103                                            (Container) event.getData());
  104               } else if (Container.REMOVE_CHILD_EVENT.equals(type)) {
  105                   processContainerRemoveChild(event.getContainer(),
  106                                               (Container) event.getData());
  107               }
  108           } catch (Exception e) {
  109               log.error("Exception processing event " + event, e);
  110           }
  111   
  112       }
  113   
  114   
  115       // ---------------------------------------------- LifecycleListener Methods
  116   
  117   
  118       /**
  119        * Primary entry point for startup and shutdown events.
  120        *
  121        * @param event The event that has occurred
  122        */
  123       public void lifecycleEvent(LifecycleEvent event) {
  124   
  125           Lifecycle lifecycle = event.getLifecycle();
  126           if (Lifecycle.START_EVENT.equals(event.getType())) {
  127   
  128               if (lifecycle instanceof Server) {
  129                   createMBeans();
  130               }
  131   
  132               // We are embedded.
  133               if( lifecycle instanceof Service ) {
  134                   try {
  135                       MBeanFactory factory = new MBeanFactory();
  136                       createMBeans(factory);
  137                       createMBeans((Service)lifecycle);
  138                   } catch( Exception ex ) {
  139                       log.error("Create mbean factory");
  140                   }
  141               }
  142   
  143               /*
  144               // Ignore events from StandardContext objects to avoid
  145               // reregistering the context
  146               if (lifecycle instanceof StandardContext)
  147                   return;
  148               createMBeans();
  149               */
  150   
  151           } else if (Lifecycle.STOP_EVENT.equals(event.getType())) {
  152               try {
  153                   if (lifecycle instanceof Server) {
  154                       destroyMBeans((Server)lifecycle);
  155                   }
  156                   if (lifecycle instanceof Service) {
  157                       destroyMBeans((Service)lifecycle);
  158                   }
  159               } catch (MBeanException t) {
  160   
  161                   Exception e = t.getTargetException();
  162                   if (e == null) {
  163                       e = t;
  164                   }
  165                   log.error("destroyMBeans: MBeanException", e);
  166   
  167               } catch (Throwable t) {
  168   
  169                   log.error("destroyMBeans: Throwable", t);
  170   
  171               }
  172               // FIXME: RMI adaptor should be stopped; however, this is
  173               // undocumented in MX4J, and reports exist in the MX4J bug DB that
  174               // this doesn't work
  175   
  176           }
  177   
  178           if ((Context.RELOAD_EVENT.equals(event.getType()))
  179               || (Lifecycle.START_EVENT.equals(event.getType()))) {
  180   
  181               // Give context a new handle to the MBean server if the
  182               // context has been reloaded since reloading causes the
  183               // context to lose its previous handle to the server
  184               if (lifecycle instanceof StandardContext) {
  185                   // If the context is privileged, give a reference to it
  186                   // in a servlet context attribute
  187                   StandardContext context = (StandardContext)lifecycle;
  188                   if (context.getPrivileged()) {
  189                       context.getServletContext().setAttribute
  190                           (Globals.MBEAN_REGISTRY_ATTR,
  191                            MBeanUtils.createRegistry());
  192                       context.getServletContext().setAttribute
  193                           (Globals.MBEAN_SERVER_ATTR,
  194                            MBeanUtils.createServer());
  195                   }
  196               }
  197   
  198           }
  199   
  200       }
  201   
  202   
  203       // ----------------------------------------- PropertyChangeListener Methods
  204   
  205   
  206       /**
  207        * Handle a <code>PropertyChangeEvent</code> from one of the Containers
  208        * we are interested in.
  209        *
  210        * @param event The event that has occurred
  211        */
  212       public void propertyChange(PropertyChangeEvent event) {
  213   
  214           if (event.getSource() instanceof Container) {
  215               try {
  216                   processContainerPropertyChange((Container) event.getSource(),
  217                                                  event.getPropertyName(),
  218                                                  event.getOldValue(),
  219                                                  event.getNewValue());
  220               } catch (Exception e) {
  221                   log.error("Exception handling Container property change", e);
  222               }
  223           }/* else if (event.getSource() instanceof DefaultContext) {
  224               try {
  225                   processDefaultContextPropertyChange
  226                       ((DefaultContext) event.getSource(),
  227                        event.getPropertyName(),
  228                        event.getOldValue(),
  229                        event.getNewValue());
  230               } catch (Exception e) {
  231                   log.error("Exception handling DefaultContext property change", e);
  232               }
  233           }*/ else if (event.getSource() instanceof NamingResources) {
  234               try {
  235                   processNamingResourcesPropertyChange
  236                       ((NamingResources) event.getSource(),
  237                        event.getPropertyName(),
  238                        event.getOldValue(),
  239                        event.getNewValue());
  240               } catch (Exception e) {
  241                   log.error("Exception handling NamingResources property change", e);
  242               }
  243           } else if (event.getSource() instanceof Server) {
  244               try {
  245                   processServerPropertyChange((Server) event.getSource(),
  246                                               event.getPropertyName(),
  247                                               event.getOldValue(),
  248                                               event.getNewValue());
  249               } catch (Exception e) {
  250                   log.error("Exception handing Server property change", e);
  251               }
  252           } else if (event.getSource() instanceof Service) {
  253               try {
  254                   processServicePropertyChange((Service) event.getSource(),
  255                                                event.getPropertyName(),
  256                                                event.getOldValue(),
  257                                                event.getNewValue());
  258               } catch (Exception e) {
  259                   log.error("Exception handing Service property change", e);
  260               }
  261           }
  262   
  263       }
  264   
  265   
  266       // ------------------------------------------------------ Protected Methods
  267   
  268   
  269       /**
  270        * Create the MBeans that correspond to every existing node of our tree.
  271        */
  272       protected void createMBeans() {
  273   
  274           try {
  275   
  276               MBeanFactory factory = new MBeanFactory();
  277               createMBeans(factory);
  278               createMBeans(ServerFactory.getServer());
  279   
  280           } catch (MBeanException t) {
  281   
  282               Exception e = t.getTargetException();
  283               if (e == null)
  284                   e = t;
  285               log.error("createMBeans: MBeanException", e);
  286   
  287           } catch (Throwable t) {
  288   
  289               log.error("createMBeans: Throwable", t);
  290   
  291           }
  292   
  293       }
  294   
  295   
  296       /**
  297        * Create the MBeans for the specified Connector and its nested components.
  298        *
  299        * @param connector Connector for which to create MBeans
  300        *
  301        * @exception Exception if an exception is thrown during MBean creation
  302        */
  303       protected void createMBeans(Connector connector) throws Exception {
  304   
  305           // Create the MBean for the Connnector itself
  306   //        if (log.isDebugEnabled())
  307   //            log.debug("Creating MBean for Connector " + connector);
  308   //        MBeanUtils.createMBean(connector);
  309   
  310       }
  311   
  312   
  313       /**
  314        * Create the MBeans for the specified Context and its nested components.
  315        *
  316        * @param context Context for which to create MBeans
  317        *
  318        * @exception Exception if an exception is thrown during MBean creation
  319        */
  320       protected void createMBeans(Context context) throws Exception {
  321   
  322           // Create the MBean for the Context itself
  323   //        if (log.isDebugEnabled())
  324   //            log.debug("Creating MBean for Context " + context);
  325   //        MBeanUtils.createMBean(context);
  326           context.addContainerListener(this);
  327           if (context instanceof StandardContext) {
  328               ((StandardContext) context).addPropertyChangeListener(this);
  329               ((StandardContext) context).addLifecycleListener(this);
  330           }
  331   
  332           // If the context is privileged, give a reference to it
  333           // in a servlet context attribute
  334           if (context.getPrivileged()) {
  335               context.getServletContext().setAttribute
  336                   (Globals.MBEAN_REGISTRY_ATTR,
  337                    MBeanUtils.createRegistry());
  338               context.getServletContext().setAttribute
  339                   (Globals.MBEAN_SERVER_ATTR,
  340                    MBeanUtils.createServer());
  341           }
  342   
  343           // Create the MBeans for the associated nested components
  344           Loader cLoader = context.getLoader();
  345           if (cLoader != null) {
  346               if (log.isDebugEnabled())
  347                   log.debug("Creating MBean for Loader " + cLoader);
  348               //MBeanUtils.createMBean(cLoader);
  349           }
  350           Manager cManager = context.getManager();
  351           if (cManager != null) {
  352               if (log.isDebugEnabled())
  353                   log.debug("Creating MBean for Manager " + cManager);
  354               //MBeanUtils.createMBean(cManager);
  355           }
  356           Realm hRealm = context.getParent().getRealm();
  357           Realm cRealm = context.getRealm();
  358           if ((cRealm != null) && (cRealm != hRealm)) {
  359               if (log.isDebugEnabled())
  360                   log.debug("Creating MBean for Realm " + cRealm);
  361               //MBeanUtils.createMBean(cRealm);
  362           }
  363   
  364           // Create the MBeans for the NamingResources (if any)
  365           NamingResources resources = context.getNamingResources();
  366           createMBeans(resources);
  367   
  368       }
  369   
  370   
  371       /**
  372        * Create the MBeans for the specified ContextEnvironment entry.
  373        *
  374        * @param environment ContextEnvironment for which to create MBeans
  375        *
  376        * @exception Exception if an exception is thrown during MBean creation
  377        */
  378       protected void createMBeans(ContextEnvironment environment)
  379           throws Exception {
  380   
  381           // Create the MBean for the ContextEnvironment itself
  382           if (log.isDebugEnabled()) {
  383               log.debug("Creating MBean for ContextEnvironment " + environment);
  384           }
  385           MBeanUtils.createMBean(environment);
  386   
  387       }
  388   
  389   
  390       /**
  391        * Create the MBeans for the specified ContextResource entry.
  392        *
  393        * @param resource ContextResource for which to create MBeans
  394        *
  395        * @exception Exception if an exception is thrown during MBean creation
  396        */
  397       protected void createMBeans(ContextResource resource)
  398           throws Exception {
  399   
  400           // Create the MBean for the ContextResource itself
  401           if (log.isDebugEnabled()) {
  402               log.debug("Creating MBean for ContextResource " + resource);
  403           }
  404           MBeanUtils.createMBean(resource);
  405   
  406       }
  407   
  408   
  409       /**
  410        * Create the MBeans for the specified ContextResourceLink entry.
  411        *
  412        * @param resourceLink ContextResourceLink for which to create MBeans
  413        *
  414        * @exception Exception if an exception is thrown during MBean creation
  415        */
  416       protected void createMBeans(ContextResourceLink resourceLink)
  417           throws Exception {
  418   
  419           // Create the MBean for the ContextResourceLink itself
  420           if (log.isDebugEnabled()) {
  421               log.debug("Creating MBean for ContextResourceLink " + resourceLink);
  422           }
  423           MBeanUtils.createMBean(resourceLink);
  424   
  425       }
  426   
  427   
  428       /**
  429        * Create the MBeans for the specified DefaultContext and its nested components.
  430        *
  431        * @param dcontext DefaultContext for which to create MBeans
  432        *
  433        * @exception Exception if an exception is thrown during MBean creation
  434        */
  435       /*
  436       protected void createMBeans(DefaultContext dcontext) throws Exception {
  437   
  438           // Create the MBean for the DefaultContext itself
  439           if (log.isDebugEnabled())
  440               log.debug("Creating MBean for DefaultContext " + dcontext);
  441           MBeanUtils.createMBean(dcontext);
  442   
  443           dcontext.addPropertyChangeListener(this);
  444   
  445           // Create the MBeans for the associated nested components
  446           Loader dLoader = dcontext.getLoader();
  447           if (dLoader != null) {
  448               if (log.isDebugEnabled())
  449                   log.debug("Creating MBean for Loader " + dLoader);
  450               //MBeanUtils.createMBean(dLoader);
  451           }
  452   
  453           Manager dManager = dcontext.getManager();
  454           if (dManager != null) {
  455               if (log.isDebugEnabled())
  456                   log.debug("Creating MBean for Manager " + dManager);
  457               //MBeanUtils.createMBean(dManager);
  458           }
  459   
  460           // Create the MBeans for the NamingResources (if any)
  461           NamingResources resources = dcontext.getNamingResources();
  462           createMBeans(resources);
  463   
  464       }
  465       */
  466   
  467   
  468       /**
  469        * Create the MBeans for the specified Engine and its nested components.
  470        *
  471        * @param engine Engine for which to create MBeans
  472        *
  473        * @exception Exception if an exception is thrown during MBean creation
  474        */
  475       protected void createMBeans(Engine engine) throws Exception {
  476   
  477           // Create the MBean for the Engine itself
  478           if (log.isDebugEnabled()) {
  479               log.debug("Creating MBean for Engine " + engine);
  480           }
  481           //MBeanUtils.createMBean(engine);
  482           engine.addContainerListener(this);
  483           if (engine instanceof StandardEngine) {
  484               ((StandardEngine) engine).addPropertyChangeListener(this);
  485           }
  486   
  487           // Create the MBeans for the associated nested components
  488           Realm eRealm = engine.getRealm();
  489           if (eRealm != null) {
  490               if (log.isDebugEnabled())
  491                   log.debug("Creating MBean for Realm " + eRealm);
  492               //MBeanUtils.createMBean(eRealm);
  493           }
  494   
  495           // Create the MBeans for each child Host
  496           Container hosts[] = engine.findChildren();
  497           for (int j = 0; j < hosts.length; j++) {
  498               createMBeans((Host) hosts[j]);
  499           }
  500   
  501       }
  502   
  503   
  504       /**
  505        * Create the MBeans for the specified Host and its nested components.
  506        *
  507        * @param host Host for which to create MBeans
  508        *
  509        * @exception Exception if an exception is thrown during MBean creation
  510        */
  511       protected void createMBeans(Host host) throws Exception {
  512   
  513           // Create the MBean for the Host itself
  514           if (log.isDebugEnabled()) {
  515               log.debug("Creating MBean for Host " + host);
  516           }
  517           //MBeanUtils.createMBean(host);
  518           host.addContainerListener(this);
  519           if (host instanceof StandardHost) {
  520               ((StandardHost) host).addPropertyChangeListener(this);
  521           }
  522   
  523           // Create the MBeans for the associated nested components
  524           Realm eRealm = host.getParent().getRealm();
  525           Realm hRealm = host.getRealm();
  526           if ((hRealm != null) && (hRealm != eRealm)) {
  527               if (log.isDebugEnabled())
  528                   log.debug("Creating MBean for Realm " + hRealm);
  529               //MBeanUtils.createMBean(hRealm);
  530           }
  531   
  532           // Create the MBeans for each child Context
  533           Container contexts[] = host.findChildren();
  534           for (int k = 0; k < contexts.length; k++) {
  535               createMBeans((Context) contexts[k]);
  536           }
  537   
  538       }
  539   
  540   
  541       /**
  542        * Create the MBeans for MBeanFactory.
  543        *
  544        * @param factory MBeanFactory for which to create MBean
  545        *
  546        * @exception Exception if an exception is thrown during MBean creation
  547        */
  548       protected void createMBeans(MBeanFactory factory) throws Exception {
  549   
  550           // Create the MBean for the MBeanFactory
  551           if (log.isDebugEnabled())
  552               log.debug("Creating MBean for MBeanFactory " + factory);
  553           MBeanUtils.createMBean(factory);
  554   
  555       }
  556   
  557   
  558       /**
  559        * Create the MBeans for the specified NamingResources and its
  560        * nested components.
  561        *
  562        * @param resources NamingResources for which to create MBeans
  563        */
  564       protected void createMBeans(NamingResources resources) throws Exception {
  565   
  566           // Create the MBean for the NamingResources itself
  567           if (log.isDebugEnabled()) {
  568               log.debug("Creating MBean for NamingResources " + resources);
  569           }
  570           MBeanUtils.createMBean(resources);
  571           resources.addPropertyChangeListener(this);
  572   
  573           // Create the MBeans for each child environment entry
  574           ContextEnvironment environments[] = resources.findEnvironments();
  575           for (int i = 0; i < environments.length; i++) {
  576               createMBeans(environments[i]);
  577           }
  578   
  579           // Create the MBeans for each child resource entry
  580           ContextResource cresources[] = resources.findResources();
  581           for (int i = 0; i < cresources.length; i++) {
  582               createMBeans(cresources[i]);
  583           }
  584   
  585           // Create the MBeans for each child resource link entry
  586           ContextResourceLink cresourcelinks[] = resources.findResourceLinks();
  587           for (int i = 0; i < cresourcelinks.length; i++) {
  588               createMBeans(cresourcelinks[i]);
  589           }
  590   
  591       }
  592   
  593   
  594       /**
  595        * Create the MBeans for the specified Server and its nested components.
  596        *
  597        * @param server Server for which to create MBeans
  598        *
  599        * @exception Exception if an exception is thrown during MBean creation
  600        */
  601       protected void createMBeans(Server server) throws Exception {
  602   
  603           // Create the MBean for the Server itself
  604           if (log.isDebugEnabled())
  605               log.debug("Creating MBean for Server " + server);
  606           //MBeanUtils.createMBean(server);
  607           if (server instanceof StandardServer) {
  608               ((StandardServer) server).addPropertyChangeListener(this);
  609           }
  610   
  611           // Create the MBeans for the global NamingResources (if any)
  612           NamingResources resources = server.getGlobalNamingResources();
  613           if (resources != null) {
  614               createMBeans(resources);
  615           }
  616   
  617           // Create the MBeans for each child Service
  618           Service services[] = server.findServices();
  619           for (int i = 0; i < services.length; i++) {
  620               // FIXME - Warp object hierarchy not currently supported
  621               if (services[i].getContainer().getClass().getName().equals
  622                   ("org.apache.catalina.connector.warp.WarpEngine")) {
  623                   if (log.isDebugEnabled()) {
  624                       log.debug("Skipping MBean for Service " + services[i]);
  625                   }
  626                   continue;
  627               }
  628               createMBeans(services[i]);
  629           }
  630   
  631       }
  632   
  633   
  634       /**
  635        * Create the MBeans for the specified Service and its nested components.
  636        *
  637        * @param service Service for which to create MBeans
  638        *
  639        * @exception Exception if an exception is thrown during MBean creation
  640        */
  641       protected void createMBeans(Service service) throws Exception {
  642   
  643           // Create the MBean for the Service itself
  644           if (log.isDebugEnabled())
  645               log.debug("Creating MBean for Service " + service);
  646           //MBeanUtils.createMBean(service);
  647           if (service instanceof StandardService) {
  648               ((StandardService) service).addPropertyChangeListener(this);
  649           }
  650   
  651           // Create the MBeans for the corresponding Connectors
  652           Connector connectors[] = service.findConnectors();
  653           for (int j = 0; j < connectors.length; j++) {
  654               createMBeans(connectors[j]);
  655           }
  656   
  657           // Create the MBean for the associated Engine and friends
  658           Engine engine = (Engine) service.getContainer();
  659           if (engine != null) {
  660               createMBeans(engine);
  661           }
  662   
  663       }
  664   
  665   
  666   
  667   
  668       /**
  669        * Deregister the MBeans for the specified Connector and its nested
  670        * components.
  671        *
  672        * @param connector Connector for which to deregister MBeans
  673        *
  674        * @exception Exception if an exception is thrown during MBean destruction
  675        */
  676       protected void destroyMBeans(Connector connector, Service service)
  677           throws Exception {
  678   
  679   //        // deregister the MBean for the Connector itself
  680   //        if (log.isDebugEnabled())
  681   //            log.debug("Destroying MBean for Connector " + connector);
  682   //        MBeanUtils.destroyMBean(connector, service);
  683   
  684       }
  685   
  686   
  687       /**
  688        * Deregister the MBeans for the specified Context and its nested
  689        * components.
  690        *
  691        * @param context Context for which to deregister MBeans
  692        *
  693        * @exception Exception if an exception is thrown during MBean destruction
  694        */
  695       protected void destroyMBeans(Context context) throws Exception {
  696   
  697           // Deregister ourselves as a ContainerListener
  698           context.removeContainerListener(this);
  699   
  700           // Destroy the MBeans for the associated nested components
  701           Realm hRealm = context.getParent().getRealm();
  702           Realm cRealm = context.getRealm();
  703           if ((cRealm != null) && (cRealm != hRealm)) {
  704               if (log.isDebugEnabled())
  705                   log.debug("Destroying MBean for Realm " + cRealm);
  706               //MBeanUtils.destroyMBean(cRealm);
  707           }
  708           Manager cManager = context.getManager();
  709           if (cManager != null) {
  710               if (log.isDebugEnabled())
  711                   log.debug("Destroying MBean for Manager " + cManager);
  712               //MBeanUtils.destroyMBean(cManager);
  713           }
  714           Loader cLoader = context.getLoader();
  715           if (cLoader != null) {
  716               if (log.isDebugEnabled())
  717                   log.debug("Destroying MBean for Loader " + cLoader);
  718               //MBeanUtils.destroyMBean(cLoader);
  719           }
  720   
  721           // Destroy the MBeans for the NamingResources (if any)
  722           NamingResources resources = context.getNamingResources();
  723           if (resources != null) {
  724               destroyMBeans(resources);
  725           }
  726   
  727           // deregister the MBean for the Context itself
  728           if (log.isDebugEnabled())
  729               log.debug("Destroying MBean for Context " + context);
  730           //MBeanUtils.destroyMBean(context);
  731           if (context instanceof StandardContext) {
  732               ((StandardContext) context).
  733                   removePropertyChangeListener(this);
  734           }
  735   
  736       }
  737   
  738   
  739       /**
  740        * Deregister the MBeans for the specified ContextEnvironment entry.
  741        *
  742        * @param environment ContextEnvironment for which to destroy MBeans
  743        *
  744        * @exception Exception if an exception is thrown during MBean destruction
  745        */
  746       protected void destroyMBeans(ContextEnvironment environment)
  747           throws Exception {
  748   
  749           // Destroy the MBean for the ContextEnvironment itself
  750           if (log.isDebugEnabled()) {
  751               log.debug("Destroying MBean for ContextEnvironment " + environment);
  752           }
  753           MBeanUtils.destroyMBean(environment);
  754   
  755       }
  756   
  757   
  758       /**
  759        * Deregister the MBeans for the specified ContextResource entry.
  760        *
  761        * @param resource ContextResource for which to destroy MBeans
  762        *
  763        * @exception Exception if an exception is thrown during MBean destruction
  764        */
  765       protected void destroyMBeans(ContextResource resource)
  766           throws Exception {
  767   
  768           // Destroy the MBean for the ContextResource itself
  769           if (log.isDebugEnabled()) {
  770               log.debug("Destroying MBean for ContextResource " + resource);
  771           }
  772           MBeanUtils.destroyMBean(resource);
  773   
  774       }
  775   
  776   
  777       /**
  778        * Deregister the MBeans for the specified ContextResourceLink entry.
  779        *
  780        * @param resourceLink ContextResourceLink for which to destroy MBeans
  781        *
  782        * @exception Exception if an exception is thrown during MBean destruction
  783        */
  784       protected void destroyMBeans(ContextResourceLink resourceLink)
  785           throws Exception {
  786   
  787           // Destroy the MBean for the ContextResourceLink itself
  788           if (log.isDebugEnabled()) {
  789               log.debug("Destroying MBean for ContextResourceLink " + resourceLink);
  790           }
  791           MBeanUtils.destroyMBean(resourceLink);
  792   
  793       }
  794   
  795   
  796       /**
  797        * Deregister the MBeans for the specified DefaultContext and its nested
  798        * components.
  799        *
  800        * @param dcontext DefaultContext for which to deregister MBeans
  801        *
  802        * @exception Exception if an exception is thrown during MBean destruction
  803        */
  804       /*
  805       protected void destroyMBeans(DefaultContext dcontext) throws Exception {
  806   
  807           Manager dManager = dcontext.getManager();
  808           if (dManager != null) {
  809               if (log.isDebugEnabled())
  810                   log.debug("Destroying MBean for Manager " + dManager);
  811               //MBeanUtils.destroyMBean(dManager);
  812           }
  813   
  814           Loader dLoader = dcontext.getLoader();
  815           if (dLoader != null) {
  816               if (log.isDebugEnabled())
  817                   log.debug("Destroying MBean for Loader " + dLoader);
  818               //MBeanUtils.destroyMBean(dLoader);
  819           }
  820   
  821           // Destroy the MBeans for the NamingResources (if any)
  822           NamingResources resources = dcontext.getNamingResources();
  823           if (resources != null) {
  824               destroyMBeans(resources);
  825           }
  826   
  827           // deregister the MBean for the DefaultContext itself
  828           if (log.isDebugEnabled())
  829               log.debug("Destroying MBean for Context " + dcontext);
  830           MBeanUtils.destroyMBean(dcontext);
  831           dcontext.removePropertyChangeListener(this);
  832   
  833       }
  834       */
  835   
  836   
  837       /**
  838        * Deregister the MBeans for the specified Engine and its nested
  839        * components.
  840        *
  841        * @param engine Engine for which to destroy MBeans
  842        *
  843        * @exception Exception if an exception is thrown during MBean destruction
  844        */
  845       protected void destroyMBeans(Engine engine) throws Exception {
  846   
  847           // Deregister ourselves as a ContainerListener
  848           engine.removeContainerListener(this);
  849   
  850           // Deregister the MBeans for each child Host
  851           Container hosts[] = engine.findChildren();
  852           for (int k = 0; k < hosts.length; k++) {
  853               destroyMBeans((Host) hosts[k]);
  854           }
  855   
  856           // Deregister the MBeans for the associated nested components
  857           Realm eRealm = engine.getRealm();
  858           if (eRealm != null) {
  859               if (log.isDebugEnabled())
  860                   log.debug("Destroying MBean for Realm " + eRealm);
  861               //MBeanUtils.destroyMBean(eRealm);
  862           }
  863   
  864           // Deregister the MBean for the Engine itself
  865           if (log.isDebugEnabled()) {
  866               log.debug("Destroying MBean for Engine " + engine);
  867           }
  868           //MBeanUtils.destroyMBean(engine);
  869   
  870       }
  871   
  872   
  873       /**
  874        * Deregister the MBeans for the specified Host and its nested components.
  875        *
  876        * @param host Host for which to destroy MBeans
  877        *
  878        * @exception Exception if an exception is thrown during MBean destruction
  879        */
  880       protected void destroyMBeans(Host host) throws Exception {
  881   
  882           // Deregister ourselves as a ContainerListener
  883           host.removeContainerListener(this);
  884   
  885           // Deregister the MBeans for each child Context
  886           Container contexts[] = host.findChildren();
  887           for (int k = 0; k < contexts.length; k++) {
  888               destroyMBeans((Context) contexts[k]);
  889           }
  890   
  891   
  892           // Deregister the MBeans for the associated nested components
  893           Realm eRealm = host.getParent().getRealm();
  894           Realm hRealm = host.getRealm();
  895           if ((hRealm != null) && (hRealm != eRealm)) {
  896               if (log.isDebugEnabled())
  897                   log.debug("Destroying MBean for Realm " + hRealm);
  898               //MBeanUtils.destroyMBean(hRealm);
  899           }
  900   
  901           // Deregister the MBean for the Host itself
  902           if (log.isDebugEnabled()) {
  903               log.debug("Destroying MBean for Host " + host);
  904           }
  905           //MBeanUtils.destroyMBean(host);
  906   
  907       }
  908   
  909   
  910       /**
  911        * Deregister the MBeans for the specified NamingResources and its
  912        * nested components.
  913        *
  914        * @param resources NamingResources for which to destroy MBeans
  915        *
  916        * @exception Exception if an exception is thrown during MBean destruction
  917        */
  918       protected void destroyMBeans(NamingResources resources) throws Exception {
  919   
  920           // Destroy the MBeans for each child resource entry
  921           ContextResource cresources[] = resources.findResources();
  922           for (int i = 0; i < cresources.length; i++) {
  923               destroyMBeans(cresources[i]);
  924           }
  925   
  926           // Destroy the MBeans for each child resource link entry
  927           ContextResourceLink cresourcelinks[] = resources.findResourceLinks();
  928           for (int i = 0; i < cresourcelinks.length; i++) {
  929               destroyMBeans(cresourcelinks[i]);
  930           }
  931   
  932           // Destroy the MBeans for each child environment entry
  933           ContextEnvironment environments[] = resources.findEnvironments();
  934           for (int i = 0; i < environments.length; i++) {
  935               destroyMBeans(environments[i]);
  936           }
  937   
  938           // Destroy the MBean for the NamingResources itself
  939           if (log.isDebugEnabled()) {
  940               log.debug("Destroying MBean for NamingResources " + resources);
  941           }
  942           MBeanUtils.destroyMBean(resources);
  943           resources.removePropertyChangeListener(this);
  944   
  945       }
  946   
  947   
  948       /**
  949        * Deregister the MBeans for the specified Server and its related
  950        * components.
  951        *
  952        * @param server Server for which to destroy MBeans
  953        *
  954        * @exception Exception if an exception is thrown during MBean destruction
  955        */
  956       protected void destroyMBeans(Server server) throws Exception {
  957   
  958           // Destroy the MBeans for the global NamingResources (if any)
  959           NamingResources resources = server.getGlobalNamingResources();
  960           if (resources != null) {
  961               destroyMBeans(resources);
  962           }
  963   
  964           // Destroy the MBeans for each child Service
  965           Service services[] = server.findServices();
  966           for (int i = 0; i < services.length; i++) {
  967               // FIXME - Warp object hierarchy not currently supported
  968               if (services[i].getContainer().getClass().getName().equals
  969                   ("org.apache.catalina.connector.warp.WarpEngine")) {
  970                   if (log.isDebugEnabled()) {
  971                       log.debug("Skipping MBean for Service " + services[i]);
  972                   }
  973                   continue;
  974               }
  975               destroyMBeans(services[i]);
  976           }
  977   
  978           // Destroy the MBean for the Server itself
  979           if (log.isDebugEnabled()) {
  980               log.debug("Destroying MBean for Server " + server);
  981           }
  982           //MBeanUtils.destroyMBean(server);
  983           if (server instanceof StandardServer) {
  984               ((StandardServer) server).removePropertyChangeListener(this);
  985           }
  986   
  987       }
  988   
  989   
  990       /**
  991        * Deregister the MBeans for the specified Service and its nested
  992        * components.
  993        *
  994        * @param service Service for which to destroy MBeans
  995        *
  996        * @exception Exception if an exception is thrown during MBean destruction
  997        */
  998       protected void destroyMBeans(Service service) throws Exception {
  999   
 1000           // Deregister the MBeans for the associated Engine
 1001           Engine engine = (Engine) service.getContainer();
 1002           if (engine != null) {
 1003               //destroyMBeans(engine);
 1004           }
 1005   
 1006   //        // Deregister the MBeans for the corresponding Connectors
 1007   //        Connector connectors[] = service.findConnectors();
 1008   //        for (int j = 0; j < connectors.length; j++) {
 1009   //            destroyMBeans(connectors[j], service);
 1010   //        }
 1011   
 1012           // Deregister the MBean for the Service itself
 1013           if (log.isDebugEnabled()) {
 1014               log.debug("Destroying MBean for Service " + service);
 1015           }
 1016           //MBeanUtils.destroyMBean(service);
 1017           if (service instanceof StandardService) {
 1018               ((StandardService) service).removePropertyChangeListener(this);
 1019           }
 1020   
 1021       }
 1022   
 1023   
 1024       /**
 1025        * Process the addition of a new child Container to a parent Container.
 1026        *
 1027        * @param parent Parent container
 1028        * @param child Child container
 1029        */
 1030       protected void processContainerAddChild(Container parent,
 1031                                               Container child) {
 1032   
 1033           if (log.isDebugEnabled())
 1034               log.debug("Process addChild[parent=" + parent + ",child=" + child + "]");
 1035   
 1036           try {
 1037               if (child instanceof Context) {
 1038                   createMBeans((Context) child);
 1039               } else if (child instanceof Engine) {
 1040                   createMBeans((Engine) child);
 1041               } else if (child instanceof Host) {
 1042                   createMBeans((Host) child);
 1043               }
 1044           } catch (MBeanException t) {
 1045               Exception e = t.getTargetException();
 1046               if (e == null)
 1047                   e = t;
 1048               log.error("processContainerAddChild: MBeanException", e);
 1049           } catch (Throwable t) {
 1050               log.error("processContainerAddChild: Throwable", t);
 1051           }
 1052   
 1053       }
 1054   
 1055   
 1056   
 1057   
 1058       /**
 1059        * Process a property change event on a Container.
 1060        *
 1061        * @param container The container on which this event occurred
 1062        * @param propertyName The name of the property that changed
 1063        * @param oldValue The previous value (may be <code>null</code>)
 1064        * @param newValue The new value (may be <code>null</code>)
 1065        *
 1066        * @exception Exception if an exception is thrown
 1067        */
 1068       protected void processContainerPropertyChange(Container container,
 1069                                                     String propertyName,
 1070                                                     Object oldValue,
 1071                                                     Object newValue)
 1072           throws Exception {
 1073   
 1074           if (log.isTraceEnabled()) {
 1075               log.trace("propertyChange[container=" + container +
 1076                   ",propertyName=" + propertyName +
 1077                   ",oldValue=" + oldValue +
 1078                   ",newValue=" + newValue + "]");
 1079           }
 1080           if ("loader".equals(propertyName)) {
 1081               if (oldValue != null) {
 1082                   if (log.isDebugEnabled()) {
 1083                       log.debug("Removing MBean for Loader " + oldValue);
 1084                   }
 1085                   MBeanUtils.destroyMBean((Loader) oldValue);
 1086               }
 1087               if (newValue != null) {
 1088                   if (log.isDebugEnabled()) {
 1089                       log.debug("Creating MBean for Loader " + newValue);
 1090                   }
 1091                   MBeanUtils.createMBean((Loader) newValue);
 1092               }
 1093           } else if ("logger".equals(propertyName)) {
 1094               if (oldValue != null) {
 1095                   if (log.isDebugEnabled()) {
 1096                       log.debug("Removing MBean for Logger " + oldValue);
 1097                   }
 1098                  // MBeanUtils.destroyMBean((Logger) oldValue);
 1099               }
 1100               if (newValue != null) {
 1101                   if (log.isDebugEnabled()) {
 1102                       log.debug("Creating MBean for Logger " + newValue);
 1103                   }
 1104                   //MBeanUtils.createMBean((Logger) newValue);
 1105               }
 1106           } else if ("manager".equals(propertyName)) {
 1107               if (oldValue != null) {
 1108                   if (log.isDebugEnabled()) {
 1109                       log.debug("Removing MBean for Manager " + oldValue);
 1110                   }
 1111                   //MBeanUtils.destroyMBean((Manager) oldValue);
 1112               }
 1113               if (newValue != null) {
 1114                   if (log.isDebugEnabled()) {
 1115                       log.debug("Creating MBean for Manager " + newValue);
 1116                   }
 1117                   //MBeanUtils.createMBean((Manager) newValue);
 1118               }
 1119           } else if ("realm".equals(propertyName)) {
 1120               if (oldValue != null) {
 1121                   if (log.isDebugEnabled()) {
 1122                       log.debug("Removing MBean for Realm " + oldValue);
 1123                   }
 1124                   MBeanUtils.destroyMBean((Realm) oldValue);
 1125               }
 1126               if (newValue != null) {
 1127                   if (log.isDebugEnabled()) {
 1128                       log.debug("Creating MBean for Realm " + newValue);
 1129                   }
 1130                   //MBeanUtils.createMBean((Realm) newValue);
 1131               }
 1132           } else if ("service".equals(propertyName)) {
 1133               if (oldValue != null) {
 1134                   destroyMBeans((Service) oldValue);
 1135               }
 1136               if (newValue != null) {
 1137                   createMBeans((Service) newValue);
 1138               }
 1139           }
 1140   
 1141       }
 1142   
 1143   
 1144       /**
 1145        * Process a property change event on a DefaultContext.
 1146        *
 1147        * @param defaultContext The DefaultContext on which this event occurred
 1148        * @param propertyName The name of the property that changed
 1149        * @param oldValue The previous value (may be <code>null</code>)
 1150        * @param newValue The new value (may be <code>null</code>)
 1151        *
 1152        * @exception Exception if an exception is thrown
 1153        */
 1154       /*
 1155       protected void processDefaultContextPropertyChange(DefaultContext defaultContext,
 1156                                                     String propertyName,
 1157                                                     Object oldValue,
 1158                                                     Object newValue)
 1159           throws Exception {
 1160   
 1161           if (log.isTraceEnabled()) {
 1162               log.trace("propertyChange[defaultContext=" + defaultContext +
 1163                   ",propertyName=" + propertyName +
 1164                   ",oldValue=" + oldValue +
 1165                   ",newValue=" + newValue + "]");
 1166           }
 1167           if ("loader".equals(propertyName)) {
 1168               if (oldValue != null) {
 1169                   if (log.isDebugEnabled()) {
 1170                       log.debug("Removing MBean for Loader " + oldValue);
 1171                   }
 1172                   MBeanUtils.destroyMBean((Loader) oldValue);
 1173               }
 1174               if (newValue != null) {
 1175                   if (log.isDebugEnabled()) {
 1176                       log.debug("Creating MBean for Loader " + newValue);
 1177                   }
 1178                   MBeanUtils.createMBean((Loader) newValue);
 1179               }
 1180           } else if ("logger".equals(propertyName)) {
 1181               if (oldValue != null) {
 1182                   if (log.isDebugEnabled()) {
 1183                       log.debug("Removing MBean for Logger " + oldValue);
 1184                   }
 1185                   //MBeanUtils.destroyMBean((Logger) oldValue);
 1186               }
 1187               if (newValue != null) {
 1188                   if (log.isDebugEnabled()) {
 1189                       log.debug("Creating MBean for Logger " + newValue);
 1190                   }
 1191                   //MBeanUtils.createMBean((Logger) newValue);
 1192               }
 1193           } else if ("manager".equals(propertyName)) {
 1194               if (oldValue != null) {
 1195                   if (log.isDebugEnabled()) {
 1196                       log.debug("Removing MBean for Manager " + oldValue);
 1197                   }
 1198                   MBeanUtils.destroyMBean((Manager) oldValue);
 1199               }
 1200               if (newValue != null) {
 1201                   if (log.isDebugEnabled()) {
 1202                       log.debug("Creating MBean for Manager " + newValue);
 1203                   }
 1204                   MBeanUtils.createMBean((Manager) newValue);
 1205               }
 1206           } else if ("realm".equals(propertyName)) {
 1207               if (oldValue != null) {
 1208   //                if (log.isDebugEnabled()) {
 1209   //                    log.debug("Removing MBean for Realm " + oldValue);
 1210   //                }
 1211   //                //MBeanUtils.destroyMBean((Realm) oldValue);
 1212               }
 1213               if (newValue != null) {
 1214   //                if (log.isDebugEnabled()) {
 1215   //                    log.debug("Creating MBean for Realm " + newValue);
 1216   //                }
 1217   //                //MBeanUtils.createMBean((Realm) newValue);
 1218               }
 1219           } else if ("service".equals(propertyName)) {
 1220               if (oldValue != null) {
 1221                   destroyMBeans((Service) oldValue);
 1222               }
 1223               if (newValue != null) {
 1224                   createMBeans((Service) newValue);
 1225               }
 1226           }
 1227   
 1228       }*/
 1229   
 1230   
 1231       /**
 1232        * Process the removal of a child Container from a parent Container.
 1233        *
 1234        * @param parent Parent container
 1235        * @param child Child container
 1236        */
 1237       protected void processContainerRemoveChild(Container parent,
 1238                                                  Container child) {
 1239   
 1240           if (log.isDebugEnabled())
 1241               log.debug("Process removeChild[parent=" + parent + ",child=" +
 1242                   child + "]");
 1243   
 1244           try {
 1245               if (child instanceof Context) {
 1246                   Context context = (Context) child;
 1247                   if (context.getPrivileged()) {
 1248                       context.getServletContext().removeAttribute
 1249                           (Globals.MBEAN_REGISTRY_ATTR);
 1250                       context.getServletContext().removeAttribute
 1251                           (Globals.MBEAN_SERVER_ATTR);
 1252                   }
 1253                   if (log.isDebugEnabled())
 1254                       log.debug("  Removing MBean for Context " + context);
 1255                   destroyMBeans(context);
 1256                   if (context instanceof StandardContext) {
 1257                       ((StandardContext) context).
 1258                           removePropertyChangeListener(this);
 1259                   }
 1260               } else if (child instanceof Host) {
 1261                   Host host = (Host) child;
 1262                   destroyMBeans(host);
 1263                   if (host instanceof StandardHost) {
 1264                       ((StandardHost) host).
 1265                           removePropertyChangeListener(this);
 1266                   }
 1267               }
 1268           } catch (MBeanException t) {
 1269               Exception e = t.getTargetException();
 1270               if (e == null)
 1271                   e = t;
 1272               log.error("processContainerRemoveChild: MBeanException", e);
 1273           } catch (Throwable t) {
 1274               log.error("processContainerRemoveChild: Throwable", t);
 1275           }
 1276   
 1277       }
 1278   
 1279   
 1280       /**
 1281        * Process a property change event on a NamingResources.
 1282        *
 1283        * @param resources The global naming resources on which this
 1284        *  event occurred
 1285        * @param propertyName The name of the property that changed
 1286        * @param oldValue The previous value (may be <code>null</code>)
 1287        * @param newValue The new value (may be <code>null</code>)
 1288        *
 1289        * @exception Exception if an exception is thrown
 1290        */
 1291       protected void processNamingResourcesPropertyChange
 1292           (NamingResources resources, String propertyName,
 1293            Object oldValue, Object newValue)
 1294           throws Exception {
 1295   
 1296           if (log.isTraceEnabled()) {
 1297               log.trace("propertyChange[namingResources=" + resources +
 1298                   ",propertyName=" + propertyName +
 1299                   ",oldValue=" + oldValue +
 1300                   ",newValue=" + newValue + "]");
 1301           }
 1302   
 1303           // FIXME - Add other resource types when supported by admin tool
 1304           if ("environment".equals(propertyName)) {
 1305               if (oldValue != null) {
 1306                   destroyMBeans((ContextEnvironment) oldValue);
 1307               }
 1308               if (newValue != null) {
 1309                   createMBeans((ContextEnvironment) newValue);
 1310               }
 1311           } else if ("resource".equals(propertyName)) {
 1312               if (oldValue != null) {
 1313                   destroyMBeans((ContextResource) oldValue);
 1314               }
 1315               if (newValue != null) {
 1316                   createMBeans((ContextResource) newValue);
 1317               }
 1318           } else if ("resourceLink".equals(propertyName)) {
 1319               if (oldValue != null) {
 1320                   destroyMBeans((ContextResourceLink) oldValue);
 1321               }
 1322               if (newValue != null) {
 1323                   createMBeans((ContextResourceLink) newValue);
 1324               }
 1325           }
 1326   
 1327       }
 1328   
 1329   
 1330       /**
 1331        * Process a property change event on a Server.
 1332        *
 1333        * @param server The server on which this event occurred
 1334        * @param propertyName The name of the property that changed
 1335        * @param oldValue The previous value (may be <code>null</code>)
 1336        * @param newValue The new value (may be <code>null</code>)
 1337        *
 1338        * @exception Exception if an exception is thrown
 1339        */
 1340       protected void processServerPropertyChange(Server server,
 1341                                                  String propertyName,
 1342                                                  Object oldValue,
 1343                                                  Object newValue)
 1344           throws Exception {
 1345   
 1346           if (log.isTraceEnabled()) {
 1347               log.trace("propertyChange[server=" + server +
 1348                   ",propertyName=" + propertyName +
 1349                   ",oldValue=" + oldValue +
 1350                   ",newValue=" + newValue + "]");
 1351           }
 1352           if ("globalNamingResources".equals(propertyName)) {
 1353               if (oldValue != null) {
 1354                   destroyMBeans((NamingResources) oldValue);
 1355               }
 1356               if (newValue != null) {
 1357                   createMBeans((NamingResources) newValue);
 1358               }
 1359           } else if ("service".equals(propertyName)) {
 1360               if (oldValue != null) {
 1361                   destroyMBeans((Service) oldValue);
 1362               }
 1363               if (newValue != null) {
 1364                   createMBeans((Service) newValue);
 1365               }
 1366           }
 1367   
 1368       }
 1369   
 1370   
 1371       /**
 1372        * Process a property change event on a Service.
 1373        *
 1374        * @param service The service on which this event occurred
 1375        * @param propertyName The name of the property that changed
 1376        * @param oldValue The previous value (may be <code>null</code>)
 1377        * @param newValue The new value (may be <code>null</code>)
 1378        *
 1379        * @exception Exception if an exception is thrown
 1380        */
 1381       protected void processServicePropertyChange(Service service,
 1382                                                   String propertyName,
 1383                                                   Object oldValue,
 1384                                                   Object newValue)
 1385           throws Exception {
 1386   
 1387           if (log.isTraceEnabled()) {
 1388               log.trace("propertyChange[service=" + service +
 1389                   ",propertyName=" + propertyName +
 1390                   ",oldValue=" + oldValue +
 1391                   ",newValue=" + newValue + "]");
 1392           }
 1393           if ("connector".equals(propertyName)) {
 1394               if (oldValue != null) {
 1395                   destroyMBeans((Connector) oldValue, service);
 1396               }
 1397               if (newValue != null) {
 1398                   createMBeans((Connector) newValue);
 1399               }
 1400           } else if ("container".equals(propertyName)) {
 1401               if (oldValue != null) {
 1402                   destroyMBeans((Engine) oldValue);
 1403               }
 1404               if (newValue != null) {
 1405                   createMBeans((Engine) newValue);
 1406               }
 1407           }
 1408   
 1409       }
 1410   
 1411   
 1412   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » mbeans » [javadoc | source]