Save This Page
Home » apache-tomcat-6.0.26-src » org.apache » catalina » core » [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   
   19   package org.apache.catalina.core;
   20   
   21   
   22   import java.io.File;
   23   import java.util.List;
   24   
   25   import javax.management.MBeanServer;
   26   import javax.management.MalformedObjectNameException;
   27   import javax.management.ObjectName;
   28   
   29   import org.apache.catalina.Container;
   30   import org.apache.catalina.Engine;
   31   import org.apache.catalina.Host;
   32   import org.apache.catalina.LifecycleException;
   33   import org.apache.catalina.Realm;
   34   import org.apache.catalina.Service;
   35   import org.apache.catalina.realm.JAASRealm;
   36   import org.apache.catalina.util.ServerInfo;
   37   import org.apache.juli.logging.Log;
   38   import org.apache.juli.logging.LogFactory;
   39   import org.apache.tomcat.util.modeler.Registry;
   40   import org.apache.tomcat.util.modeler.modules.MbeansSource;
   41   
   42   /**
   43    * Standard implementation of the <b>Engine</b> interface.  Each
   44    * child container must be a Host implementation to process the specific
   45    * fully qualified host name of that virtual host. <br/>
   46    * You can set the jvmRoute direct or with the System.property <b>jvmRoute</b>.
   47    *
   48    * @author Craig R. McClanahan
   49    * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (Tue, 24 Oct 2006) $
   50    */
   51   
   52   public class StandardEngine
   53       extends ContainerBase
   54       implements Engine {
   55   
   56       private static Log log = LogFactory.getLog(StandardEngine.class);
   57   
   58       // ----------------------------------------------------------- Constructors
   59   
   60   
   61       /**
   62        * Create a new StandardEngine component with the default basic Valve.
   63        */
   64       public StandardEngine() {
   65   
   66           super();
   67           pipeline.setBasic(new StandardEngineValve());
   68           /* Set the jmvRoute using the system property jvmRoute */
   69           try {
   70               setJvmRoute(System.getProperty("jvmRoute"));
   71           } catch(Exception ex) {
   72           }
   73           // By default, the engine will hold the reloading thread
   74           backgroundProcessorDelay = 10;
   75   
   76       }
   77   
   78   
   79       // ----------------------------------------------------- Instance Variables
   80   
   81   
   82       /**
   83        * Host name to use when no server host, or an unknown host,
   84        * is specified in the request.
   85        */
   86       private String defaultHost = null;
   87   
   88   
   89       /**
   90        * The descriptive information string for this implementation.
   91        */
   92       private static final String info =
   93           "org.apache.catalina.core.StandardEngine/1.0";
   94   
   95   
   96       /**
   97        * The <code>Service</code> that owns this Engine, if any.
   98        */
   99       private Service service = null;
  100   
  101       /** Allow the base dir to be specified explicitely for
  102        * each engine. In time we should stop using catalina.base property -
  103        * otherwise we loose some flexibility.
  104        */
  105       private String baseDir = null;
  106   
  107       /** Optional mbeans config file. This will replace the "hacks" in
  108        * jk and ServerListener. The mbeans file will support (transparent) 
  109        * persistence - soon. It'll probably replace jk2.properties and could
  110        * replace server.xml. Of course - the same beans could be loaded and 
  111        * managed by an external entity - like the embedding app - which
  112        *  can use a different persistence mechanism.
  113        */ 
  114       private String mbeansFile = null;
  115       
  116       /** Mbeans loaded by the engine.  
  117        */ 
  118       private List mbeans;
  119       
  120   
  121       /**
  122        * The JVM Route ID for this Tomcat instance. All Route ID's must be unique
  123        * across the cluster.
  124        */
  125       private String jvmRouteId;
  126   
  127   
  128       // ------------------------------------------------------------- Properties
  129   
  130       /** Provide a default in case no explicit configuration is set
  131        *
  132        * @return configured realm, or a JAAS realm by default
  133        */
  134       public Realm getRealm() {
  135           Realm configured=super.getRealm();
  136           // If no set realm has been called - default to JAAS
  137           // This can be overriden at engine, context and host level  
  138           if( configured==null ) {
  139               configured=new JAASRealm();
  140               this.setRealm( configured );
  141           }
  142           return configured;
  143       }
  144   
  145   
  146       /**
  147        * Return the default host.
  148        */
  149       public String getDefaultHost() {
  150   
  151           return (defaultHost);
  152   
  153       }
  154   
  155   
  156       /**
  157        * Set the default host.
  158        *
  159        * @param host The new default host
  160        */
  161       public void setDefaultHost(String host) {
  162   
  163           String oldDefaultHost = this.defaultHost;
  164           if (host == null) {
  165               this.defaultHost = null;
  166           } else {
  167               this.defaultHost = host.toLowerCase();
  168           }
  169           support.firePropertyChange("defaultHost", oldDefaultHost,
  170                                      this.defaultHost);
  171   
  172       }
  173       
  174       public void setName(String name ) {
  175           if( domain != null ) {
  176               // keep name==domain, ignore override
  177               // we are already registered
  178               super.setName( domain );
  179               return;
  180           }
  181           // The engine name is used as domain
  182           domain=name; // XXX should we set it in init() ? It shouldn't matter
  183           super.setName( name );
  184       }
  185   
  186   
  187       /**
  188        * Set the cluster-wide unique identifier for this Engine.
  189        * This value is only useful in a load-balancing scenario.
  190        * <p>
  191        * This property should not be changed once it is set.
  192        */
  193       public void setJvmRoute(String routeId) {
  194           jvmRouteId = routeId;
  195       }
  196   
  197   
  198       /**
  199        * Retrieve the cluster-wide unique identifier for this Engine.
  200        * This value is only useful in a load-balancing scenario.
  201        */
  202       public String getJvmRoute() {
  203           return jvmRouteId;
  204       }
  205   
  206   
  207       /**
  208        * Return the <code>Service</code> with which we are associated (if any).
  209        */
  210       public Service getService() {
  211   
  212           return (this.service);
  213   
  214       }
  215   
  216   
  217       /**
  218        * Set the <code>Service</code> with which we are associated (if any).
  219        *
  220        * @param service The service that owns this Engine
  221        */
  222       public void setService(Service service) {
  223           this.service = service;
  224       }
  225   
  226       public String getMbeansFile() {
  227           return mbeansFile;
  228       }
  229   
  230       public void setMbeansFile(String mbeansFile) {
  231           this.mbeansFile = mbeansFile;
  232       }
  233   
  234       public String getBaseDir() {
  235           if( baseDir==null ) {
  236               baseDir=System.getProperty("catalina.base");
  237           }
  238           if( baseDir==null ) {
  239               baseDir=System.getProperty("catalina.home");
  240           }
  241           return baseDir;
  242       }
  243   
  244       public void setBaseDir(String baseDir) {
  245           this.baseDir = baseDir;
  246       }
  247   
  248       // --------------------------------------------------------- Public Methods
  249   
  250   
  251       /**
  252        * Add a child Container, only if the proposed child is an implementation
  253        * of Host.
  254        *
  255        * @param child Child container to be added
  256        */
  257       public void addChild(Container child) {
  258   
  259           if (!(child instanceof Host))
  260               throw new IllegalArgumentException
  261                   (sm.getString("standardEngine.notHost"));
  262           super.addChild(child);
  263   
  264       }
  265   
  266   
  267       /**
  268        * Return descriptive information about this Container implementation and
  269        * the corresponding version number, in the format
  270        * <code>&lt;description&gt;/&lt;version&gt;</code>.
  271        */
  272       public String getInfo() {
  273   
  274           return (info);
  275   
  276       }
  277   
  278       /**
  279        * Disallow any attempt to set a parent for this Container, since an
  280        * Engine is supposed to be at the top of the Container hierarchy.
  281        *
  282        * @param container Proposed parent Container
  283        */
  284       public void setParent(Container container) {
  285   
  286           throw new IllegalArgumentException
  287               (sm.getString("standardEngine.notParent"));
  288   
  289       }
  290   
  291   
  292       private boolean initialized=false;
  293       
  294       public void init() {
  295           if( initialized ) return;
  296           initialized=true;
  297   
  298           if( oname==null ) {
  299               // not registered in JMX yet - standalone mode
  300               try {
  301                   if (domain==null) {
  302                       domain=getName();
  303                   }
  304                   if(log.isDebugEnabled())
  305                       log.debug( "Register " + domain );
  306                   oname=new ObjectName(domain + ":type=Engine");
  307                   controller=oname;
  308                   Registry.getRegistry(null, null)
  309                       .registerComponent(this, oname, null);
  310               } catch( Throwable t ) {
  311                   log.info("Error registering ", t );
  312               }
  313           }
  314   
  315           if( mbeansFile == null ) {
  316               String defaultMBeansFile=getBaseDir() + "/conf/tomcat5-mbeans.xml";
  317               File f=new File( defaultMBeansFile );
  318               if( f.exists() ) mbeansFile=f.getAbsolutePath();
  319           }
  320           if( mbeansFile != null ) {
  321               readEngineMbeans();
  322           }
  323           if( mbeans != null ) {
  324               try {
  325                   Registry.getRegistry(null, null).invoke(mbeans, "init", false);
  326               } catch (Exception e) {
  327                   log.error("Error in init() for " + mbeansFile, e);
  328               }
  329           }
  330           
  331           // not needed since the following if statement does the same thing the right way
  332           // remove later after checking
  333           //if( service==null ) {
  334           //    try {
  335           //        ObjectName serviceName=getParentName();        
  336           //        if( mserver.isRegistered( serviceName )) {
  337           //            log.info("Registering with the service ");
  338           //            try {
  339           //                mserver.invoke( serviceName, "setContainer",
  340           //                        new Object[] { this },
  341           //                        new String[] { "org.apache.catalina.Container" } );
  342           //            } catch( Exception ex ) {
  343           //               ex.printStackTrace();
  344           //            }
  345           //        }
  346           //    } catch( Exception ex ) {
  347           //        log.error("Error registering with service ");
  348           //    }
  349           //}
  350           
  351           if( service==null ) {
  352               // for consistency...: we are probably in embeded mode
  353               try {
  354                   service=new StandardService();
  355                   service.setContainer( this );
  356                   service.initialize();
  357               } catch( Throwable t ) {
  358                   log.error(t);
  359               }
  360           }
  361           
  362       }
  363       
  364       public void destroy() throws LifecycleException {
  365           if( ! initialized ) return;
  366           initialized=false;
  367           
  368           // if we created it, make sure it's also destroyed
  369           // this call implizit this.stop()
  370           ((StandardService)service).destroy();
  371   
  372           if( mbeans != null ) {
  373               try {
  374                   Registry.getRegistry(null, null)
  375                       .invoke(mbeans, "destroy", false);
  376               } catch (Exception e) {
  377                   log.error(sm.getString("standardEngine.unregister.mbeans.failed" ,mbeansFile), e);
  378               }
  379           }
  380           // 
  381           if( mbeans != null ) {
  382               try {
  383                   for( int i=0; i<mbeans.size() ; i++ ) {
  384                       Registry.getRegistry(null, null)
  385                           .unregisterComponent((ObjectName)mbeans.get(i));
  386                   }
  387               } catch (Exception e) {
  388                   log.error(sm.getString("standardEngine.unregister.mbeans.failed", mbeansFile), e);
  389               }
  390           }
  391           
  392           // force all metadata to be reloaded.
  393           // That doesn't affect existing beans. We should make it per
  394           // registry - and stop using the static.
  395           Registry.getRegistry(null, null).resetMetadata();
  396           
  397       }
  398       
  399       /**
  400        * Start this Engine component.
  401        *
  402        * @exception LifecycleException if a startup error occurs
  403        */
  404       public void start() throws LifecycleException {
  405           if( started ) {
  406               return;
  407           }
  408           if( !initialized ) {
  409               init();
  410           }
  411   
  412           // Look for a realm - that may have been configured earlier. 
  413           // If the realm is added after context - it'll set itself.
  414           if( realm == null ) {
  415               ObjectName realmName=null;
  416               try {
  417                   realmName=new ObjectName( domain + ":type=Realm");
  418                   if( mserver.isRegistered(realmName ) ) {
  419                       mserver.invoke(realmName, "init", 
  420                               new Object[] {},
  421                               new String[] {}
  422                       );            
  423                   }
  424               } catch( Throwable t ) {
  425                   log.debug("No realm for this engine " + realmName);
  426               }
  427           }
  428               
  429           // Log our server identification information
  430           //System.out.println(ServerInfo.getServerInfo());
  431           if(log.isInfoEnabled())
  432               log.info( "Starting Servlet Engine: " + ServerInfo.getServerInfo());
  433           if( mbeans != null ) {
  434               try {
  435                   Registry.getRegistry(null, null)
  436                       .invoke(mbeans, "start", false);
  437               } catch (Exception e) {
  438                   log.error("Error in start() for " + mbeansFile, e);
  439               }
  440           }
  441   
  442           // Standard container startup
  443           super.start();
  444   
  445       }
  446       
  447       public void stop() throws LifecycleException {
  448           super.stop();
  449           if( mbeans != null ) {
  450               try {
  451                   Registry.getRegistry(null, null).invoke(mbeans, "stop", false);
  452               } catch (Exception e) {
  453                   log.error("Error in stop() for " + mbeansFile, e);
  454               }
  455           }
  456       }
  457   
  458   
  459       /**
  460        * Return a String representation of this component.
  461        */
  462       public String toString() {
  463   
  464           StringBuffer sb = new StringBuffer("StandardEngine[");
  465           sb.append(getName());
  466           sb.append("]");
  467           return (sb.toString());
  468   
  469       }
  470   
  471   
  472       // ------------------------------------------------------ Protected Methods
  473   
  474   
  475       // -------------------- JMX registration  --------------------
  476   
  477       public ObjectName preRegister(MBeanServer server,
  478                                     ObjectName name) throws Exception
  479       {
  480           super.preRegister(server,name);
  481   
  482           this.setName( name.getDomain());
  483   
  484           return name;
  485       }
  486   
  487       // FIXME Remove -- not used 
  488       public ObjectName getParentName() throws MalformedObjectNameException {
  489           if (getService()==null) {
  490               return null;
  491           }
  492           String name = getService().getName();
  493           ObjectName serviceName=new ObjectName(domain +
  494                           ":type=Service,serviceName="+name);
  495           return serviceName;                
  496       }
  497       
  498       public ObjectName createObjectName(String domain, ObjectName parent)
  499           throws Exception
  500       {
  501           if( log.isDebugEnabled())
  502               log.debug("Create ObjectName " + domain + " " + parent );
  503           return new ObjectName( domain + ":type=Engine");
  504       }
  505   
  506       
  507       private void readEngineMbeans() {
  508           try {
  509               MbeansSource mbeansMB=new MbeansSource();
  510               File mbeansF=new File( mbeansFile );
  511               mbeansMB.setSource(mbeansF);
  512               
  513               Registry.getRegistry(null, null).registerComponent
  514                   (mbeansMB, domain + ":type=MbeansFile", null);
  515               mbeansMB.load();
  516               mbeansMB.init();
  517               mbeansMB.setRegistry(Registry.getRegistry(null, null));
  518               mbeans=mbeansMB.getMBeans();
  519               
  520           } catch( Throwable t ) {
  521               log.error( "Error loading " + mbeansFile, t );
  522           }
  523           
  524       }
  525       
  526       public String getDomain() {
  527           if (domain!=null) {
  528               return domain;
  529           } else { 
  530               return getName();
  531           }
  532       }
  533       
  534       public void setDomain(String domain) {
  535           this.domain = domain;
  536       }
  537       
  538   }

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