Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » startup » [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.startup;
   20   
   21   
   22   import java.io.File;
   23   import java.io.IOException;
   24   import java.net.InetAddress;
   25   import java.util.HashMap;
   26   
   27   import org.apache.catalina.Authenticator;
   28   import org.apache.catalina.Container;
   29   import org.apache.catalina.Context;
   30   import org.apache.catalina.Engine;
   31   import org.apache.catalina.Host;
   32   import org.apache.catalina.Lifecycle;
   33   import org.apache.catalina.LifecycleException;
   34   import org.apache.catalina.LifecycleListener;
   35   import org.apache.catalina.Loader;
   36   import org.apache.catalina.Realm;
   37   import org.apache.catalina.Valve;
   38   import org.apache.catalina.connector.Connector;
   39   import org.apache.catalina.core.StandardContext;
   40   import org.apache.catalina.core.StandardEngine;
   41   import org.apache.catalina.core.StandardHost;
   42   import org.apache.catalina.core.StandardService;
   43   import org.apache.catalina.loader.WebappLoader;
   44   import org.apache.catalina.security.SecurityConfig;
   45   import org.apache.catalina.util.LifecycleSupport;
   46   import org.apache.catalina.util.StringManager;
   47   import org.apache.juli.logging.Log;
   48   import org.apache.juli.logging.LogFactory;
   49   import org.apache.tomcat.util.IntrospectionUtils;
   50   import org.apache.tomcat.util.log.SystemLogHandler;
   51   
   52   
   53   /**
   54    * Convenience class to embed a Catalina servlet container environment
   55    * inside another application.  You must call the methods of this class in the
   56    * following order to ensure correct operation.
   57    *
   58    * <ul>
   59    * <li>Instantiate a new instance of this class.</li>
   60    * <li>Set the relevant properties of this object itself.  In particular,
   61    *     you will want to establish the default Logger to be used, as well
   62    *     as the default Realm if you are using container-managed security.</li>
   63    * <li>Call <code>createEngine()</code> to create an Engine object, and then
   64    *     call its property setters as desired.</li>
   65    * <li>Call <code>createHost()</code> to create at least one virtual Host
   66    *     associated with the newly created Engine, and then call its property
   67    *     setters as desired.  After you customize this Host, add it to the
   68    *     corresponding Engine with <code>engine.addChild(host)</code>.</li>
   69    * <li>Call <code>createContext()</code> to create at least one Context
   70    *     associated with each newly created Host, and then call its property
   71    *     setters as desired.  You <strong>SHOULD</strong> create a Context with
   72    *     a pathname equal to a zero-length string, which will be used to process
   73    *     all requests not mapped to some other Context.  After you customize
   74    *     this Context, add it to the corresponding Host with
   75    *     <code>host.addChild(context)</code>.</li>
   76    * <li>Call <code>addEngine()</code> to attach this Engine to the set of
   77    *     defined Engines for this object.</li>
   78    * <li>Call <code>createConnector()</code> to create at least one TCP/IP
   79    *     connector, and then call its property setters as desired.</li>
   80    * <li>Call <code>addConnector()</code> to attach this Connector to the set
   81    *     of defined Connectors for this object.  The added Connector will use
   82    *     the most recently added Engine to process its received requests.</li>
   83    * <li>Repeat the above series of steps as often as required (although there
   84    *     will typically be only one Engine instance created).</li>
   85    * <li>Call <code>start()</code> to initiate normal operations of all the
   86    *     attached components.</li>
   87    * </ul>
   88    *
   89    * After normal operations have begun, you can add and remove Connectors,
   90    * Engines, Hosts, and Contexts on the fly.  However, once you have removed
   91    * a particular component, it must be thrown away -- you can create a new one
   92    * with the same characteristics if you merely want to do a restart.
   93    * <p>
   94    * To initiate a normal shutdown, call the <code>stop()</code> method of
   95    * this object.
   96    * <p>
   97    * @see org.apache.catalina.startup.Catalina#main For a complete example
   98    * of how Tomcat is set up and launched as an Embedded application.
   99    *
  100    * @author Craig R. McClanahan
  101    * @version $Revision: 586738 $ $Date: 2007-10-20 16:57:18 +0200 (sam., 20 oct. 2007) $
  102    */
  103   
  104   public class Embedded  extends StandardService implements Lifecycle {
  105       private static Log log = LogFactory.getLog(Embedded.class);
  106   
  107       // ----------------------------------------------------------- Constructors
  108   
  109   
  110       /**
  111        * Construct a new instance of this class with default properties.
  112        */
  113       public Embedded() {
  114   
  115           this(null);
  116   
  117       }
  118   
  119   
  120       /**
  121        * Construct a new instance of this class with specified properties.
  122        *
  123        * @param realm Realm implementation to be inherited by all components
  124        *  (unless overridden further down the container hierarchy)
  125        */
  126       public Embedded(Realm realm) {
  127   
  128           super();
  129           setRealm(realm);
  130           setSecurityProtection();
  131           
  132       }
  133   
  134   
  135       // ----------------------------------------------------- Instance Variables
  136   
  137   
  138       /**
  139        * Is naming enabled ?
  140        */
  141       protected boolean useNaming = true;
  142   
  143   
  144       /**
  145        * Is standard streams redirection enabled ?
  146        */
  147       protected boolean redirectStreams = true;
  148   
  149   
  150       /**
  151        * The set of Engines that have been deployed in this server.  Normally
  152        * there will only be one.
  153        */
  154       protected Engine engines[] = new Engine[0];
  155   
  156   
  157       /**
  158        * Custom mappings of login methods to authenticators
  159        */
  160       protected HashMap authenticators;
  161   
  162   
  163       /**
  164        * Descriptive information about this server implementation.
  165        */
  166       protected static final String info =
  167           "org.apache.catalina.startup.Embedded/1.0";
  168   
  169   
  170       /**
  171        * The lifecycle event support for this component.
  172        */
  173       protected LifecycleSupport lifecycle = new LifecycleSupport(this);
  174   
  175   
  176       /**
  177        * The default realm to be used by all containers associated with
  178        * this compoennt.
  179        */
  180       protected Realm realm = null;
  181   
  182   
  183       /**
  184        * The string manager for this package.
  185        */
  186       protected static StringManager sm =
  187           StringManager.getManager(Constants.Package);
  188   
  189   
  190       /**
  191        * Has this component been started yet?
  192        */
  193       protected boolean started = false;
  194   
  195       /**
  196        * Use await.
  197        */
  198       protected boolean await = false;
  199   
  200   
  201       // ------------------------------------------------------------- Properties
  202   
  203   
  204       /**
  205        * Return true if naming is enabled.
  206        */
  207       public boolean isUseNaming() {
  208   
  209           return (this.useNaming);
  210   
  211       }
  212   
  213   
  214       /**
  215        * Enables or disables naming support.
  216        *
  217        * @param useNaming The new use naming value
  218        */
  219       public void setUseNaming(boolean useNaming) {
  220   
  221           boolean oldUseNaming = this.useNaming;
  222           this.useNaming = useNaming;
  223           support.firePropertyChange("useNaming", new Boolean(oldUseNaming),
  224                                      new Boolean(this.useNaming));
  225   
  226       }
  227   
  228   
  229       /**
  230        * Return true if redirction of standard streams is enabled.
  231        */
  232       public boolean isRedirectStreams() {
  233   
  234           return (this.redirectStreams);
  235   
  236       }
  237   
  238   
  239       /**
  240        * Enables or disables naming support.
  241        *
  242        * @param useNaming The new use naming value
  243        */
  244       public void setRedirectStreams(boolean redirectStreams) {
  245   
  246           boolean oldRedirectStreams = this.redirectStreams;
  247           this.redirectStreams = redirectStreams;
  248           support.firePropertyChange("redirectStreams", new Boolean(oldRedirectStreams),
  249                                      new Boolean(this.redirectStreams));
  250   
  251       }
  252   
  253   
  254       /**
  255        * Return the default Realm for our Containers.
  256        */
  257       public Realm getRealm() {
  258   
  259           return (this.realm);
  260   
  261       }
  262   
  263   
  264       /**
  265        * Set the default Realm for our Containers.
  266        *
  267        * @param realm The new default realm
  268        */
  269       public void setRealm(Realm realm) {
  270   
  271           Realm oldRealm = this.realm;
  272           this.realm = realm;
  273           support.firePropertyChange("realm", oldRealm, this.realm);
  274   
  275       }
  276   
  277       public void setAwait(boolean b) {
  278           await = b;
  279       }
  280   
  281       public boolean isAwait() {
  282           return await;
  283       }
  284   
  285       public void setCatalinaHome( String s ) {
  286           System.setProperty( "catalina.home", s);
  287       }
  288   
  289       public void setCatalinaBase( String s ) {
  290           System.setProperty( "catalina.base", s);
  291       }
  292   
  293       public String getCatalinaHome() {
  294           return System.getProperty("catalina.home");
  295       }
  296   
  297       public String getCatalinaBase() {
  298           return System.getProperty("catalina.base");
  299       }
  300   
  301   
  302       // --------------------------------------------------------- Public Methods
  303   
  304       /**
  305        * Add a new Connector to the set of defined Connectors.  The newly
  306        * added Connector will be associated with the most recently added Engine.
  307        *
  308        * @param connector The connector to be added
  309        *
  310        * @exception IllegalStateException if no engines have been added yet
  311        */
  312       public synchronized void addConnector(Connector connector) {
  313   
  314           if( log.isDebugEnabled() ) {
  315               log.debug("Adding connector (" + connector.getInfo() + ")");
  316           }
  317   
  318           // Make sure we have a Container to send requests to
  319           if (engines.length < 1)
  320               throw new IllegalStateException
  321                   (sm.getString("embedded.noEngines"));
  322   
  323           /*
  324            * Add the connector. This will set the connector's container to the
  325            * most recently added Engine
  326            */
  327           super.addConnector(connector);
  328       }
  329   
  330   
  331       /**
  332        * Add a new Engine to the set of defined Engines.
  333        *
  334        * @param engine The engine to be added
  335        */
  336       public synchronized void addEngine(Engine engine) {
  337   
  338           if( log.isDebugEnabled() )
  339               log.debug("Adding engine (" + engine.getInfo() + ")");
  340   
  341           // Add this Engine to our set of defined Engines
  342           Engine results[] = new Engine[engines.length + 1];
  343           for (int i = 0; i < engines.length; i++)
  344               results[i] = engines[i];
  345           results[engines.length] = engine;
  346           engines = results;
  347   
  348           // Start this Engine if necessary
  349           if (started && (engine instanceof Lifecycle)) {
  350               try {
  351                   ((Lifecycle) engine).start();
  352               } catch (LifecycleException e) {
  353                   log.error("Engine.start", e);
  354               }
  355           }
  356   
  357           this.container = engine;
  358       }
  359   
  360   
  361       /**
  362        * Create, configure, and return a new TCP/IP socket connector
  363        * based on the specified properties.
  364        *
  365        * @param address InetAddress to bind to, or <code>null</code> if the
  366        * connector is supposed to bind to all addresses on this server
  367        * @param port Port number to listen to
  368        * @param secure true if the generated connector is supposed to be
  369        * SSL-enabled, and false otherwise
  370        */
  371       public Connector createConnector(InetAddress address, int port,
  372                                        boolean secure) {
  373   	return createConnector(address != null? address.toString() : null,
  374   			       port, secure);
  375       }
  376   
  377       public Connector createConnector(String address, int port,
  378                                        boolean secure) {
  379           String protocol = "http";
  380           if (secure) {
  381               protocol = "https";
  382           }
  383   
  384           return createConnector(address, port, protocol);
  385       }
  386   
  387   
  388       public Connector createConnector(InetAddress address, int port,
  389                                        String protocol) {
  390   	return createConnector(address != null? address.toString() : null,
  391   			       port, protocol);
  392       }
  393   
  394       public Connector createConnector(String address, int port,
  395   				     String protocol) {
  396   
  397           Connector connector = null;
  398   
  399   	if (address != null) {
  400   	    /*
  401   	     * InetAddress.toString() returns a string of the form
  402   	     * "<hostname>/<literal_IP>". Get the latter part, so that the
  403   	     * address can be parsed (back) into an InetAddress using
  404   	     * InetAddress.getByName().
  405   	     */
  406   	    int index = address.indexOf('/');
  407   	    if (index != -1) {
  408   		address = address.substring(index + 1);
  409   	    }
  410   	}
  411   
  412   	if (log.isDebugEnabled()) {
  413               log.debug("Creating connector for address='" +
  414   		      ((address == null) ? "ALL" : address) +
  415   		      "' port='" + port + "' protocol='" + protocol + "'");
  416   	}
  417   
  418           try {
  419   
  420               if (protocol.equals("ajp")) {
  421                   connector = new Connector("org.apache.jk.server.JkCoyoteHandler");
  422               } else if (protocol.equals("memory")) {
  423                   connector = new Connector("org.apache.coyote.memory.MemoryProtocolHandler");
  424               } else if (protocol.equals("http")) {
  425                   connector = new Connector();
  426               } else if (protocol.equals("https")) {
  427                   connector = new Connector();
  428                   connector.setScheme("https");
  429                   connector.setSecure(true);
  430                   connector.setProperty("SSLEnabled","true");
  431                   // FIXME !!!! SET SSL PROPERTIES
  432               } else {
  433                   connector = new Connector(protocol);
  434               }
  435   
  436               if (address != null) {
  437                   IntrospectionUtils.setProperty(connector, "address", 
  438                                                  "" + address);
  439               }
  440               IntrospectionUtils.setProperty(connector, "port", "" + port);
  441   
  442           } catch (Exception e) {
  443               log.error("Couldn't create connector.");
  444           } 
  445   
  446           return (connector);
  447   
  448       }
  449   
  450       /**
  451        * Create, configure, and return a Context that will process all
  452        * HTTP requests received from one of the associated Connectors,
  453        * and directed to the specified context path on the virtual host
  454        * to which this Context is connected.
  455        * <p>
  456        * After you have customized the properties, listeners, and Valves
  457        * for this Context, you must attach it to the corresponding Host
  458        * by calling:
  459        * <pre>
  460        *   host.addChild(context);
  461        * </pre>
  462        * which will also cause the Context to be started if the Host has
  463        * already been started.
  464        *
  465        * @param path Context path of this application ("" for the default
  466        *  application for this host, must start with a slash otherwise)
  467        * @param docBase Absolute pathname to the document base directory
  468        *  for this web application
  469        *
  470        * @exception IllegalArgumentException if an invalid parameter
  471        *  is specified
  472        */
  473       public Context createContext(String path, String docBase) {
  474   
  475           if( log.isDebugEnabled() )
  476               log.debug("Creating context '" + path + "' with docBase '" +
  477                          docBase + "'");
  478   
  479           StandardContext context = new StandardContext();
  480   
  481           context.setDocBase(docBase);
  482           context.setPath(path);
  483   
  484           ContextConfig config = new ContextConfig();
  485           config.setCustomAuthenticators(authenticators);
  486           ((Lifecycle) context).addLifecycleListener(config);
  487   
  488           return (context);
  489   
  490       }
  491   
  492   
  493       /**
  494        * Create, configure, and return an Engine that will process all
  495        * HTTP requests received from one of the associated Connectors,
  496        * based on the specified properties.
  497        */
  498       public Engine createEngine() {
  499   
  500           if( log.isDebugEnabled() )
  501               log.debug("Creating engine");
  502   
  503           StandardEngine engine = new StandardEngine();
  504   
  505           // Default host will be set to the first host added
  506           engine.setRealm(realm);         // Inherited by all children
  507   
  508           return (engine);
  509   
  510       }
  511   
  512   
  513       /**
  514        * Create, configure, and return a Host that will process all
  515        * HTTP requests received from one of the associated Connectors,
  516        * and directed to the specified virtual host.
  517        * <p>
  518        * After you have customized the properties, listeners, and Valves
  519        * for this Host, you must attach it to the corresponding Engine
  520        * by calling:
  521        * <pre>
  522        *   engine.addChild(host);
  523        * </pre>
  524        * which will also cause the Host to be started if the Engine has
  525        * already been started.  If this is the default (or only) Host you
  526        * will be defining, you may also tell the Engine to pass all requests
  527        * not assigned to another virtual host to this one:
  528        * <pre>
  529        *   engine.setDefaultHost(host.getName());
  530        * </pre>
  531        *
  532        * @param name Canonical name of this virtual host
  533        * @param appBase Absolute pathname to the application base directory
  534        *  for this virtual host
  535        *
  536        * @exception IllegalArgumentException if an invalid parameter
  537        *  is specified
  538        */
  539       public Host createHost(String name, String appBase) {
  540   
  541           if( log.isDebugEnabled() )
  542               log.debug("Creating host '" + name + "' with appBase '" +
  543                          appBase + "'");
  544   
  545           StandardHost host = new StandardHost();
  546   
  547           host.setAppBase(appBase);
  548           host.setName(name);
  549   
  550           return (host);
  551   
  552       }
  553   
  554   
  555       /**
  556        * Create and return a class loader manager that can be customized, and
  557        * then attached to a Context, before it is started.
  558        *
  559        * @param parent ClassLoader that will be the parent of the one
  560        *  created by this Loader
  561        */
  562       public Loader createLoader(ClassLoader parent) {
  563   
  564           if( log.isDebugEnabled() )
  565               log.debug("Creating Loader with parent class loader '" +
  566                          parent + "'");
  567   
  568           WebappLoader loader = new WebappLoader(parent);
  569           return (loader);
  570   
  571       }
  572   
  573   
  574       /**
  575        * Return descriptive information about this Server implementation and
  576        * the corresponding version number, in the format
  577        * <code>&lt;description&gt;/&lt;version&gt;</code>.
  578        */
  579       public String getInfo() {
  580   
  581           return (info);
  582   
  583       }
  584   
  585   
  586       /**
  587        * Remove the specified Context from the set of defined Contexts for its
  588        * associated Host.  If this is the last Context for this Host, the Host
  589        * will also be removed.
  590        *
  591        * @param context The Context to be removed
  592        */
  593       public synchronized void removeContext(Context context) {
  594   
  595           if( log.isDebugEnabled() )
  596               log.debug("Removing context[" + context.getPath() + "]");
  597   
  598           // Is this Context actually among those that are defined?
  599           boolean found = false;
  600           for (int i = 0; i < engines.length; i++) {
  601               Container hosts[] = engines[i].findChildren();
  602               for (int j = 0; j < hosts.length; j++) {
  603                   Container contexts[] = hosts[j].findChildren();
  604                   for (int k = 0; k < contexts.length; k++) {
  605                       if (context == (Context) contexts[k]) {
  606                           found = true;
  607                           break;
  608                       }
  609                   }
  610                   if (found)
  611                       break;
  612               }
  613               if (found)
  614                   break;
  615           }
  616           if (!found)
  617               return;
  618   
  619           // Remove this Context from the associated Host
  620           if( log.isDebugEnabled() )
  621               log.debug(" Removing this Context");
  622           context.getParent().removeChild(context);
  623   
  624       }
  625   
  626   
  627       /**
  628        * Remove the specified Engine from the set of defined Engines, along with
  629        * all of its related Hosts and Contexts.  All associated Connectors are
  630        * also removed.
  631        *
  632        * @param engine The Engine to be removed
  633        */
  634       public synchronized void removeEngine(Engine engine) {
  635   
  636           if( log.isDebugEnabled() )
  637               log.debug("Removing engine (" + engine.getInfo() + ")");
  638   
  639           // Is the specified Engine actually defined?
  640           int j = -1;
  641           for (int i = 0; i < engines.length; i++) {
  642               if (engine == engines[i]) {
  643                   j = i;
  644                   break;
  645               }
  646           }
  647           if (j < 0)
  648               return;
  649   
  650           // Remove any Connector that is using this Engine
  651           if( log.isDebugEnabled() )
  652               log.debug(" Removing related Containers");
  653           while (true) {
  654               int n = -1;
  655               for (int i = 0; i < connectors.length; i++) {
  656                   if (connectors[i].getContainer() == (Container) engine) {
  657                       n = i;
  658                       break;
  659                   }
  660               }
  661               if (n < 0)
  662                   break;
  663               removeConnector(connectors[n]);
  664           }
  665   
  666           // Stop this Engine if necessary
  667           if (engine instanceof Lifecycle) {
  668               if( log.isDebugEnabled() )
  669                   log.debug(" Stopping this Engine");
  670               try {
  671                   ((Lifecycle) engine).stop();
  672               } catch (LifecycleException e) {
  673                   log.error("Engine.stop", e);
  674               }
  675           }
  676   
  677           // Remove this Engine from our set of defined Engines
  678           if( log.isDebugEnabled() )
  679               log.debug(" Removing this Engine");
  680           int k = 0;
  681           Engine results[] = new Engine[engines.length - 1];
  682           for (int i = 0; i < engines.length; i++) {
  683               if (i != j)
  684                   results[k++] = engines[i];
  685           }
  686           engines = results;
  687   
  688       }
  689   
  690   
  691       /**
  692        * Remove the specified Host, along with all of its related Contexts,
  693        * from the set of defined Hosts for its associated Engine.  If this is
  694        * the last Host for this Engine, the Engine will also be removed.
  695        *
  696        * @param host The Host to be removed
  697        */
  698       public synchronized void removeHost(Host host) {
  699   
  700           if( log.isDebugEnabled() )
  701               log.debug("Removing host[" + host.getName() + "]");
  702   
  703           // Is this Host actually among those that are defined?
  704           boolean found = false;
  705           for (int i = 0; i < engines.length; i++) {
  706               Container hosts[] = engines[i].findChildren();
  707               for (int j = 0; j < hosts.length; j++) {
  708                   if (host == (Host) hosts[j]) {
  709                       found = true;
  710                       break;
  711   
  712                   }
  713               }
  714               if (found)
  715                   break;
  716           }
  717           if (!found)
  718               return;
  719   
  720           // Remove this Host from the associated Engine
  721           if( log.isDebugEnabled() )
  722               log.debug(" Removing this Host");
  723           host.getParent().removeChild(host);
  724   
  725       }
  726   
  727   
  728       /*
  729        * Maps the specified login method to the specified authenticator, allowing
  730        * the mappings in org/apache/catalina/startup/Authenticators.properties
  731        * to be overridden.
  732        *
  733        * @param authenticator Authenticator to handle authentication for the
  734        * specified login method
  735        * @param loginMethod Login method that maps to the specified authenticator
  736        *
  737        * @throws IllegalArgumentException if the specified authenticator does not
  738        * implement the org.apache.catalina.Valve interface
  739        */
  740       public void addAuthenticator(Authenticator authenticator,
  741                                    String loginMethod) {
  742           if (!(authenticator instanceof Valve)) {
  743               throw new IllegalArgumentException(
  744                   sm.getString("embedded.authenticatorNotInstanceOfValve"));
  745           }
  746           if (authenticators == null) {
  747               synchronized (this) {
  748                   if (authenticators == null) {
  749                       authenticators = new HashMap();
  750                   }
  751               }
  752           }
  753           authenticators.put(loginMethod, authenticator);
  754       }
  755   
  756   
  757       // ------------------------------------------------------ Lifecycle Methods
  758   
  759   
  760       /**
  761        * Add a lifecycle event listener to this component.
  762        *
  763        * @param listener The listener to add
  764        */
  765       public void addLifecycleListener(LifecycleListener listener) {
  766   
  767           lifecycle.addLifecycleListener(listener);
  768   
  769       }
  770   
  771   
  772       /**
  773        * Get the lifecycle listeners associated with this lifecycle. If this 
  774        * Lifecycle has no listeners registered, a zero-length array is returned.
  775        */
  776       public LifecycleListener[] findLifecycleListeners() {
  777   
  778           return lifecycle.findLifecycleListeners();
  779   
  780       }
  781   
  782   
  783       /**
  784        * Remove a lifecycle event listener from this component.
  785        *
  786        * @param listener The listener to remove
  787        */
  788       public void removeLifecycleListener(LifecycleListener listener) {
  789   
  790           lifecycle.removeLifecycleListener(listener);
  791   
  792       }
  793   
  794   
  795       /**
  796        * Prepare for the beginning of active use of the public methods of this
  797        * component.  This method should be called after <code>configure()</code>,
  798        * and before any of the public methods of the component are utilized.
  799        *
  800        * @exception LifecycleException if this component detects a fatal error
  801        *  that prevents this component from being used
  802        */
  803       public void start() throws LifecycleException {
  804   
  805           if( log.isInfoEnabled() )
  806               log.info("Starting tomcat server");
  807   
  808           // Validate the setup of our required system properties
  809           initDirs();
  810   
  811           // Initialize some naming specific properties
  812           initNaming();
  813   
  814           // Validate and update our current component state
  815           if (started)
  816               throw new LifecycleException
  817                   (sm.getString("embedded.alreadyStarted"));
  818           lifecycle.fireLifecycleEvent(START_EVENT, null);
  819           started = true;
  820           initialized = true;
  821   
  822           // Start our defined Engines first
  823           for (int i = 0; i < engines.length; i++) {
  824               if (engines[i] instanceof Lifecycle)
  825                   ((Lifecycle) engines[i]).start();
  826           }
  827   
  828           // Start our defined Connectors second
  829           for (int i = 0; i < connectors.length; i++) {
  830               connectors[i].initialize();
  831               if (connectors[i] instanceof Lifecycle)
  832                   ((Lifecycle) connectors[i]).start();
  833           }
  834   
  835       }
  836   
  837   
  838       /**
  839        * Gracefully terminate the active use of the public methods of this
  840        * component.  This method should be the last one called on a given
  841        * instance of this component.
  842        *
  843        * @exception LifecycleException if this component detects a fatal error
  844        *  that needs to be reported
  845        */
  846       public void stop() throws LifecycleException {
  847   
  848           if( log.isDebugEnabled() )
  849               log.debug("Stopping embedded server");
  850   
  851           // Validate and update our current component state
  852           if (!started)
  853               throw new LifecycleException
  854                   (sm.getString("embedded.notStarted"));
  855           lifecycle.fireLifecycleEvent(STOP_EVENT, null);
  856           started = false;
  857   
  858           // Stop our defined Connectors first
  859           for (int i = 0; i < connectors.length; i++) {
  860               if (connectors[i] instanceof Lifecycle)
  861                   ((Lifecycle) connectors[i]).stop();
  862           }
  863   
  864           // Stop our defined Engines second
  865           for (int i = 0; i < engines.length; i++) {
  866               if (engines[i] instanceof Lifecycle)
  867                   ((Lifecycle) engines[i]).stop();
  868           }
  869   
  870       }
  871   
  872   
  873       // ------------------------------------------------------ Protected Methods
  874   
  875   
  876       /** Initialize naming - this should only enable java:env and root naming.
  877        * If tomcat is embeded in an application that already defines those -
  878        * it shouldn't do it.
  879        *
  880        * XXX The 2 should be separated, you may want to enable java: but not
  881        * the initial context and the reverse
  882        * XXX Can we "guess" - i.e. lookup java: and if something is returned assume
  883        * false ?
  884        * XXX We have a major problem with the current setting for java: url
  885        */
  886       protected void initNaming() {
  887           // Setting additional variables
  888           if (!useNaming) {
  889               log.info( "Catalina naming disabled");
  890               System.setProperty("catalina.useNaming", "false");
  891           } else {
  892               System.setProperty("catalina.useNaming", "true");
  893               String value = "org.apache.naming";
  894               String oldValue =
  895                   System.getProperty(javax.naming.Context.URL_PKG_PREFIXES);
  896               if (oldValue != null) {
  897                   value = value + ":" + oldValue;
  898               }
  899               System.setProperty(javax.naming.Context.URL_PKG_PREFIXES, value);
  900               if( log.isDebugEnabled() )
  901                   log.debug("Setting naming prefix=" + value);
  902               value = System.getProperty
  903                   (javax.naming.Context.INITIAL_CONTEXT_FACTORY);
  904               if (value == null) {
  905                   System.setProperty
  906                       (javax.naming.Context.INITIAL_CONTEXT_FACTORY,
  907                        "org.apache.naming.java.javaURLContextFactory");
  908               } else {
  909                   log.debug( "INITIAL_CONTEXT_FACTORY alread set " + value );
  910               }
  911           }
  912       }
  913   
  914   
  915       protected void initDirs() {
  916   
  917           String catalinaHome = System.getProperty("catalina.home");
  918           if (catalinaHome == null) {
  919               // Backwards compatibility patch for J2EE RI 1.3
  920               String j2eeHome = System.getProperty("com.sun.enterprise.home");
  921               if (j2eeHome != null) {
  922                   catalinaHome=System.getProperty("com.sun.enterprise.home");
  923               } else if (System.getProperty("catalina.base") != null) {
  924                   catalinaHome = System.getProperty("catalina.base");
  925               } else {
  926                   // Use IntrospectionUtils and guess the dir
  927                   catalinaHome = IntrospectionUtils.guessInstall
  928                       ("catalina.home", "catalina.base", "catalina.jar");
  929                   if (catalinaHome == null) {
  930                       catalinaHome = IntrospectionUtils.guessInstall
  931                           ("tomcat.install", "catalina.home", "tomcat.jar");
  932                   }
  933               }
  934           }
  935           // last resort - for minimal/embedded cases. 
  936           if(catalinaHome==null) {
  937               catalinaHome=System.getProperty("user.dir");
  938           }
  939           if (catalinaHome != null) {
  940               File home = new File(catalinaHome);
  941               if (!home.isAbsolute()) {
  942                   try {
  943                       catalinaHome = home.getCanonicalPath();
  944                   } catch (IOException e) {
  945                       catalinaHome = home.getAbsolutePath();
  946                   }
  947               }
  948               System.setProperty("catalina.home", catalinaHome);
  949           }
  950   
  951           if (System.getProperty("catalina.base") == null) {
  952               System.setProperty("catalina.base",
  953                                  catalinaHome);
  954           } else {
  955               String catalinaBase = System.getProperty("catalina.base");
  956               File base = new File(catalinaBase);
  957               if (!base.isAbsolute()) {
  958                   try {
  959                       catalinaBase = base.getCanonicalPath();
  960                   } catch (IOException e) {
  961                       catalinaBase = base.getAbsolutePath();
  962                   }
  963               }
  964               System.setProperty("catalina.base", catalinaBase);
  965           }
  966           
  967           String temp = System.getProperty("java.io.tmpdir");
  968           if (temp == null || (!(new File(temp)).exists())
  969                   || (!(new File(temp)).isDirectory())) {
  970               log.error(sm.getString("embedded.notmp", temp));
  971           }
  972   
  973       }
  974   
  975       
  976       protected void initStreams() {
  977           if (redirectStreams) {
  978               // Replace System.out and System.err with a custom PrintStream
  979               SystemLogHandler systemlog = new SystemLogHandler(System.out);
  980               System.setOut(systemlog);
  981               System.setErr(systemlog);
  982           }
  983       }
  984       
  985   
  986       // -------------------------------------------------------- Private Methods
  987   
  988       /**
  989        * Set the security package access/protection.
  990        */
  991       protected void setSecurityProtection(){
  992           SecurityConfig securityConfig = SecurityConfig.newInstance();
  993           securityConfig.setPackageDefinition();
  994           securityConfig.setPackageAccess();
  995       }
  996   
  997   }

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