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.FileInputStream;
   24   import java.io.IOException;
   25   import java.io.InputStream;
   26   import java.io.OutputStream;
   27   import java.net.InetAddress;
   28   import java.net.Socket;
   29   import java.util.ArrayList;
   30   import java.util.HashMap;
   31   import java.util.List;
   32   
   33   import org.apache.catalina.Container;
   34   import org.apache.catalina.Lifecycle;
   35   import org.apache.catalina.LifecycleException;
   36   import org.apache.catalina.Server;
   37   import org.apache.catalina.core.StandardServer;
   38   import org.apache.tomcat.util.digester.Digester;
   39   import org.apache.tomcat.util.digester.Rule;
   40   import org.xml.sax.Attributes;
   41   import org.xml.sax.InputSource;
   42   
   43   
   44   /**
   45    * Startup/Shutdown shell program for Catalina.  The following command line
   46    * options are recognized:
   47    * <ul>
   48    * <li><b>-config {pathname}</b> - Set the pathname of the configuration file
   49    *     to be processed.  If a relative path is specified, it will be
   50    *     interpreted as relative to the directory pathname specified by the
   51    *     "catalina.base" system property.   [conf/server.xml]
   52    * <li><b>-help</b> - Display usage information.
   53    * <li><b>-stop</b> - Stop the currently running instance of Catalina.
   54    * </u>
   55    *
   56    * Should do the same thing as Embedded, but using a server.xml file.
   57    *
   58    * @author Craig R. McClanahan
   59    * @author Remy Maucherat
   60    * @version $Revision: 596761 $ $Date: 2007-11-20 19:19:00 +0100 (mar., 20 nov. 2007) $
   61    */
   62   
   63   public class Catalina extends Embedded {
   64   
   65   
   66       // ----------------------------------------------------- Instance Variables
   67   
   68   
   69       /**
   70        * Pathname to the server configuration file.
   71        */
   72       protected String configFile = "conf/server.xml";
   73   
   74       // XXX Should be moved to embedded
   75       /**
   76        * The shared extensions class loader for this server.
   77        */
   78       protected ClassLoader parentClassLoader =
   79           Catalina.class.getClassLoader();
   80   
   81   
   82       /**
   83        * The server component we are starting or stopping
   84        */
   85       protected Server server = null;
   86   
   87   
   88       /**
   89        * Are we starting a new server?
   90        */
   91       protected boolean starting = false;
   92   
   93   
   94       /**
   95        * Are we stopping an existing server?
   96        */
   97       protected boolean stopping = false;
   98   
   99   
  100       /**
  101        * Use shutdown hook flag.
  102        */
  103       protected boolean useShutdownHook = true;
  104   
  105   
  106       /**
  107        * Shutdown hook.
  108        */
  109       protected Thread shutdownHook = null;
  110   
  111   
  112       // ------------------------------------------------------------- Properties
  113   
  114   
  115       public void setConfig(String file) {
  116           configFile = file;
  117       }
  118   
  119   
  120       public void setConfigFile(String file) {
  121           configFile = file;
  122       }
  123   
  124   
  125       public String getConfigFile() {
  126           return configFile;
  127       }
  128   
  129   
  130       public void setUseShutdownHook(boolean useShutdownHook) {
  131           this.useShutdownHook = useShutdownHook;
  132       }
  133   
  134   
  135       public boolean getUseShutdownHook() {
  136           return useShutdownHook;
  137       }
  138   
  139   
  140       /**
  141        * Set the shared extensions class loader.
  142        *
  143        * @param parentClassLoader The shared extensions class loader.
  144        */
  145       public void setParentClassLoader(ClassLoader parentClassLoader) {
  146   
  147           this.parentClassLoader = parentClassLoader;
  148   
  149       }
  150   
  151   
  152       /**
  153        * Set the server instance we are configuring.
  154        *
  155        * @param server The new server
  156        */
  157       public void setServer(Server server) {
  158   
  159           this.server = server;
  160   
  161       }
  162   
  163       // ----------------------------------------------------------- Main Program
  164   
  165       /**
  166        * The application main program.
  167        *
  168        * @param args Command line arguments
  169        */
  170       public static void main(String args[]) {
  171           (new Catalina()).process(args);
  172       }
  173   
  174   
  175       /**
  176        * The instance main program.
  177        *
  178        * @param args Command line arguments
  179        */
  180       public void process(String args[]) {
  181   
  182           setAwait(true);
  183           setCatalinaHome();
  184           setCatalinaBase();
  185           try {
  186               if (arguments(args)) {
  187                   if (starting) {
  188                       load(args);
  189                       start();
  190                   } else if (stopping) {
  191                       stopServer();
  192                   }
  193               }
  194           } catch (Exception e) {
  195               e.printStackTrace(System.out);
  196           }
  197       }
  198   
  199   
  200       // ------------------------------------------------------ Protected Methods
  201   
  202   
  203       /**
  204        * Process the specified command line arguments, and return
  205        * <code>true</code> if we should continue processing; otherwise
  206        * return <code>false</code>.
  207        *
  208        * @param args Command line arguments to process
  209        */
  210       protected boolean arguments(String args[]) {
  211   
  212           boolean isConfig = false;
  213   
  214           if (args.length < 1) {
  215               usage();
  216               return (false);
  217           }
  218   
  219           for (int i = 0; i < args.length; i++) {
  220               if (isConfig) {
  221                   configFile = args[i];
  222                   isConfig = false;
  223               } else if (args[i].equals("-config")) {
  224                   isConfig = true;
  225               } else if (args[i].equals("-nonaming")) {
  226                   setUseNaming( false );
  227               } else if (args[i].equals("-help")) {
  228                   usage();
  229                   return (false);
  230               } else if (args[i].equals("start")) {
  231                   starting = true;
  232                   stopping = false;
  233               } else if (args[i].equals("stop")) {
  234                   starting = false;
  235                   stopping = true;
  236               } else {
  237                   usage();
  238                   return (false);
  239               }
  240           }
  241   
  242           return (true);
  243   
  244       }
  245   
  246   
  247       /**
  248        * Return a File object representing our configuration file.
  249        */
  250       protected File configFile() {
  251   
  252           File file = new File(configFile);
  253           if (!file.isAbsolute())
  254               file = new File(System.getProperty("catalina.base"), configFile);
  255           return (file);
  256   
  257       }
  258   
  259   
  260       /**
  261        * Create and configure the Digester we will be using for startup.
  262        */
  263       protected Digester createStartDigester() {
  264           long t1=System.currentTimeMillis();
  265           // Initialize the digester
  266           Digester digester = new Digester();
  267           digester.setValidating(false);
  268           digester.setRulesValidation(true);
  269           HashMap<Class, List<String>> fakeAttributes = new HashMap<Class, List<String>>();
  270           ArrayList<String> attrs = new ArrayList<String>();
  271           attrs.add("className");
  272           fakeAttributes.put(Object.class, attrs);
  273           digester.setFakeAttributes(fakeAttributes);
  274           digester.setClassLoader(StandardServer.class.getClassLoader());
  275   
  276           // Configure the actions we will be using
  277           digester.addObjectCreate("Server",
  278                                    "org.apache.catalina.core.StandardServer",
  279                                    "className");
  280           digester.addSetProperties("Server");
  281           digester.addSetNext("Server",
  282                               "setServer",
  283                               "org.apache.catalina.Server");
  284   
  285           digester.addObjectCreate("Server/GlobalNamingResources",
  286                                    "org.apache.catalina.deploy.NamingResources");
  287           digester.addSetProperties("Server/GlobalNamingResources");
  288           digester.addSetNext("Server/GlobalNamingResources",
  289                               "setGlobalNamingResources",
  290                               "org.apache.catalina.deploy.NamingResources");
  291   
  292           digester.addObjectCreate("Server/Listener",
  293                                    null, // MUST be specified in the element
  294                                    "className");
  295           digester.addSetProperties("Server/Listener");
  296           digester.addSetNext("Server/Listener",
  297                               "addLifecycleListener",
  298                               "org.apache.catalina.LifecycleListener");
  299   
  300           digester.addObjectCreate("Server/Service",
  301                                    "org.apache.catalina.core.StandardService",
  302                                    "className");
  303           digester.addSetProperties("Server/Service");
  304           digester.addSetNext("Server/Service",
  305                               "addService",
  306                               "org.apache.catalina.Service");
  307   
  308           digester.addObjectCreate("Server/Service/Listener",
  309                                    null, // MUST be specified in the element
  310                                    "className");
  311           digester.addSetProperties("Server/Service/Listener");
  312           digester.addSetNext("Server/Service/Listener",
  313                               "addLifecycleListener",
  314                               "org.apache.catalina.LifecycleListener");
  315   
  316           //Executor
  317           digester.addObjectCreate("Server/Service/Executor",
  318                            "org.apache.catalina.core.StandardThreadExecutor",
  319                            "className");
  320           digester.addSetProperties("Server/Service/Executor");
  321   
  322           digester.addSetNext("Server/Service/Executor",
  323                               "addExecutor",
  324                               "org.apache.catalina.Executor");
  325   
  326           
  327           digester.addRule("Server/Service/Connector",
  328                            new ConnectorCreateRule());
  329           digester.addRule("Server/Service/Connector", 
  330                            new SetAllPropertiesRule(new String[]{"executor"}));
  331           digester.addSetNext("Server/Service/Connector",
  332                               "addConnector",
  333                               "org.apache.catalina.connector.Connector");
  334           
  335           
  336   
  337   
  338           digester.addObjectCreate("Server/Service/Connector/Listener",
  339                                    null, // MUST be specified in the element
  340                                    "className");
  341           digester.addSetProperties("Server/Service/Connector/Listener");
  342           digester.addSetNext("Server/Service/Connector/Listener",
  343                               "addLifecycleListener",
  344                               "org.apache.catalina.LifecycleListener");
  345   
  346           // Add RuleSets for nested elements
  347           digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
  348           digester.addRuleSet(new EngineRuleSet("Server/Service/"));
  349           digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
  350           digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/"));
  351           digester.addRuleSet(ClusterRuleSetFactory.getClusterRuleSet("Server/Service/Engine/Host/Cluster/"));
  352           digester.addRuleSet(new NamingRuleSet("Server/Service/Engine/Host/Context/"));
  353   
  354           // When the 'engine' is found, set the parentClassLoader.
  355           digester.addRule("Server/Service/Engine",
  356                            new SetParentClassLoaderRule(parentClassLoader));
  357           digester.addRuleSet(ClusterRuleSetFactory.getClusterRuleSet("Server/Service/Engine/Cluster/"));
  358   
  359           long t2=System.currentTimeMillis();
  360           if (log.isDebugEnabled())
  361               log.debug("Digester for server.xml created " + ( t2-t1 ));
  362           return (digester);
  363   
  364       }
  365   
  366   
  367       /**
  368        * Create and configure the Digester we will be using for shutdown.
  369        */
  370       protected Digester createStopDigester() {
  371   
  372           // Initialize the digester
  373           Digester digester = new Digester();
  374   
  375           // Configure the rules we need for shutting down
  376           digester.addObjectCreate("Server",
  377                                    "org.apache.catalina.core.StandardServer",
  378                                    "className");
  379           digester.addSetProperties("Server");
  380           digester.addSetNext("Server",
  381                               "setServer",
  382                               "org.apache.catalina.Server");
  383   
  384           return (digester);
  385   
  386       }
  387   
  388   
  389       public void stopServer() {
  390           stopServer(null);
  391       }
  392   
  393       public void stopServer(String[] arguments) {
  394   
  395           if (arguments != null) {
  396               arguments(arguments);
  397           }
  398   
  399           if( server == null ) {
  400               // Create and execute our Digester
  401               Digester digester = createStopDigester();
  402               digester.setClassLoader(Thread.currentThread().getContextClassLoader());
  403               File file = configFile();
  404               try {
  405                   InputSource is =
  406                       new InputSource("file://" + file.getAbsolutePath());
  407                   FileInputStream fis = new FileInputStream(file);
  408                   is.setByteStream(fis);
  409                   digester.push(this);
  410                   digester.parse(is);
  411                   fis.close();
  412               } catch (Exception e) {
  413                   log.error("Catalina.stop: ", e);
  414                   System.exit(1);
  415               }
  416           }
  417   
  418           // Stop the existing server
  419           try {
  420               String hostAddress = InetAddress.getByName("localhost").getHostAddress();
  421               Socket socket = new Socket(hostAddress, server.getPort());
  422               OutputStream stream = socket.getOutputStream();
  423               String shutdown = server.getShutdown();
  424               for (int i = 0; i < shutdown.length(); i++)
  425                   stream.write(shutdown.charAt(i));
  426               stream.flush();
  427               stream.close();
  428               socket.close();
  429           } catch (IOException e) {
  430               log.error("Catalina.stop: ", e);
  431               System.exit(1);
  432           }
  433   
  434       }
  435   
  436   
  437       /**
  438        * Set the <code>catalina.base</code> System property to the current
  439        * working directory if it has not been set.
  440        * @deprecated Use initDirs()
  441        */
  442       public void setCatalinaBase() {
  443           initDirs();
  444       }
  445   
  446       /**
  447        * Set the <code>catalina.home</code> System property to the current
  448        * working directory if it has not been set.
  449        * @deprecated Use initDirs()
  450        */
  451       public void setCatalinaHome() {
  452           initDirs();
  453       }
  454   
  455       /**
  456        * Start a new server instance.
  457        */
  458       public void load() {
  459   
  460           long t1 = System.nanoTime();
  461   
  462           initDirs();
  463   
  464           // Before digester - it may be needed
  465   
  466           initNaming();
  467   
  468           // Create and execute our Digester
  469           Digester digester = createStartDigester();
  470   
  471           InputSource inputSource = null;
  472           InputStream inputStream = null;
  473           File file = null;
  474           try {
  475               file = configFile();
  476               inputStream = new FileInputStream(file);
  477               inputSource = new InputSource("file://" + file.getAbsolutePath());
  478           } catch (Exception e) {
  479               ;
  480           }
  481           if (inputStream == null) {
  482               try {
  483                   inputStream = getClass().getClassLoader()
  484                       .getResourceAsStream(getConfigFile());
  485                   inputSource = new InputSource
  486                       (getClass().getClassLoader()
  487                        .getResource(getConfigFile()).toString());
  488               } catch (Exception e) {
  489                   ;
  490               }
  491           }
  492   
  493           // This should be included in catalina.jar
  494           // Alternative: don't bother with xml, just create it manually.
  495           if( inputStream==null ) {
  496               try {
  497                   inputStream = getClass().getClassLoader()
  498                   .getResourceAsStream("server-embed.xml");
  499                   inputSource = new InputSource
  500                   (getClass().getClassLoader()
  501                           .getResource("server-embed.xml").toString());
  502               } catch (Exception e) {
  503                   ;
  504               }
  505           }
  506           
  507   
  508           if ((inputStream == null) && (file != null)) {
  509               log.warn("Can't load server.xml from " + file.getAbsolutePath());
  510               return;
  511           }
  512   
  513           try {
  514               inputSource.setByteStream(inputStream);
  515               digester.push(this);
  516               digester.parse(inputSource);
  517               inputStream.close();
  518           } catch (Exception e) {
  519               log.warn("Catalina.start using "
  520                                  + getConfigFile() + ": " , e);
  521               return;
  522           }
  523   
  524           // Stream redirection
  525           initStreams();
  526   
  527           // Start the new server
  528           if (server instanceof Lifecycle) {
  529               try {
  530                   server.initialize();
  531               } catch (LifecycleException e) {
  532                   log.error("Catalina.start", e);
  533               }
  534           }
  535   
  536           long t2 = System.nanoTime();
  537           if(log.isInfoEnabled())
  538               log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");
  539   
  540       }
  541   
  542   
  543       /* 
  544        * Load using arguments
  545        */
  546       public void load(String args[]) {
  547   
  548           try {
  549               if (arguments(args))
  550                   load();
  551           } catch (Exception e) {
  552               e.printStackTrace(System.out);
  553           }
  554       }
  555   
  556       public void create() {
  557   
  558       }
  559   
  560       public void destroy() {
  561   
  562       }
  563   
  564       /**
  565        * Start a new server instance.
  566        */
  567       public void start() {
  568   
  569           if (server == null) {
  570               load();
  571           }
  572   
  573           long t1 = System.nanoTime();
  574           
  575           // Start the new server
  576           if (server instanceof Lifecycle) {
  577               try {
  578                   ((Lifecycle) server).start();
  579               } catch (LifecycleException e) {
  580                   log.error("Catalina.start: ", e);
  581               }
  582           }
  583   
  584           long t2 = System.nanoTime();
  585           if(log.isInfoEnabled())
  586               log.info("Server startup in " + ((t2 - t1) / 1000000) + " ms");
  587   
  588           try {
  589               // Register shutdown hook
  590               if (useShutdownHook) {
  591                   if (shutdownHook == null) {
  592                       shutdownHook = new CatalinaShutdownHook();
  593                   }
  594                   Runtime.getRuntime().addShutdownHook(shutdownHook);
  595               }
  596           } catch (Throwable t) {
  597               // This will fail on JDK 1.2. Ignoring, as Tomcat can run
  598               // fine without the shutdown hook.
  599           }
  600   
  601           if (await) {
  602               await();
  603               stop();
  604           }
  605   
  606       }
  607   
  608   
  609       /**
  610        * Stop an existing server instance.
  611        */
  612       public void stop() {
  613   
  614           try {
  615               // Remove the ShutdownHook first so that server.stop() 
  616               // doesn't get invoked twice
  617               if (useShutdownHook) {
  618                   Runtime.getRuntime().removeShutdownHook(shutdownHook);
  619               }
  620           } catch (Throwable t) {
  621               // This will fail on JDK 1.2. Ignoring, as Tomcat can run
  622               // fine without the shutdown hook.
  623           }
  624   
  625           // Shut down the server
  626           if (server instanceof Lifecycle) {
  627               try {
  628                   ((Lifecycle) server).stop();
  629               } catch (LifecycleException e) {
  630                   log.error("Catalina.stop", e);
  631               }
  632           }
  633   
  634       }
  635   
  636   
  637       /**
  638        * Await and shutdown.
  639        */
  640       public void await() {
  641   
  642           server.await();
  643   
  644       }
  645   
  646   
  647       /**
  648        * Print usage information for this application.
  649        */
  650       protected void usage() {
  651   
  652           System.out.println
  653               ("usage: java org.apache.catalina.startup.Catalina"
  654                + " [ -config {pathname} ]"
  655                + " [ -nonaming ] { start | stop }");
  656   
  657       }
  658   
  659   
  660       // --------------------------------------- CatalinaShutdownHook Inner Class
  661   
  662       // XXX Should be moved to embedded !
  663       /**
  664        * Shutdown hook which will perform a clean shutdown of Catalina if needed.
  665        */
  666       protected class CatalinaShutdownHook extends Thread {
  667   
  668           public void run() {
  669   
  670               if (server != null) {
  671                   Catalina.this.stop();
  672               }
  673               
  674           }
  675   
  676       }
  677       
  678       
  679       private static org.apache.juli.logging.Log log=
  680           org.apache.juli.logging.LogFactory.getLog( Catalina.class );
  681   
  682   }
  683   
  684   
  685   // ------------------------------------------------------------ Private Classes
  686   
  687   
  688   /**
  689    * Rule that sets the parent class loader for the top object on the stack,
  690    * which must be a <code>Container</code>.
  691    */
  692   
  693   final class SetParentClassLoaderRule extends Rule {
  694   
  695       public SetParentClassLoaderRule(ClassLoader parentClassLoader) {
  696   
  697           this.parentClassLoader = parentClassLoader;
  698   
  699       }
  700   
  701       ClassLoader parentClassLoader = null;
  702   
  703       public void begin(String namespace, String name, Attributes attributes)
  704           throws Exception {
  705   
  706           if (digester.getLogger().isDebugEnabled())
  707               digester.getLogger().debug("Setting parent class loader");
  708   
  709           Container top = (Container) digester.peek();
  710           top.setParentClassLoader(parentClassLoader);
  711   
  712       }
  713   
  714   
  715   }

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