Save This Page
Home » apache-tomcat-6.0.26-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.lang.management.ManagementFactory;
   24   import java.lang.reflect.Method;
   25   import java.net.MalformedURLException;
   26   import java.net.URL;
   27   import java.util.ArrayList;
   28   import java.util.StringTokenizer;
   29   
   30   import javax.management.MBeanServer;
   31   import javax.management.MBeanServerFactory;
   32   import javax.management.ObjectName;
   33   
   34   import org.apache.catalina.security.SecurityClassLoad;
   35   import org.apache.juli.logging.Log;
   36   import org.apache.juli.logging.LogFactory;
   37   
   38   
   39   /**
   40    * Boostrap loader for Catalina.  This application constructs a class loader
   41    * for use in loading the Catalina internal classes (by accumulating all of the
   42    * JAR files found in the "server" directory under "catalina.home"), and
   43    * starts the regular execution of the container.  The purpose of this
   44    * roundabout approach is to keep the Catalina internal classes (and any
   45    * other classes they depend on, such as an XML parser) out of the system
   46    * class path and therefore not visible to application level classes.
   47    *
   48    * @author Craig R. McClanahan
   49    * @author Remy Maucherat
   50    * @version $Revision: 832231 $ $Date: 2009-11-03 01:45:56 +0100 (Tue, 03 Nov 2009) $
   51    */
   52   
   53   public final class Bootstrap {
   54   
   55       private static Log log = LogFactory.getLog(Bootstrap.class);
   56       
   57       // -------------------------------------------------------------- Constants
   58   
   59   
   60       protected static final String CATALINA_HOME_TOKEN = "${catalina.home}";
   61       protected static final String CATALINA_BASE_TOKEN = "${catalina.base}";
   62   
   63   
   64       // ------------------------------------------------------- Static Variables
   65   
   66   
   67       /**
   68        * Daemon object used by main.
   69        */
   70       private static Bootstrap daemon = null;
   71   
   72   
   73       // -------------------------------------------------------------- Variables
   74   
   75   
   76       /**
   77        * Daemon reference.
   78        */
   79       private Object catalinaDaemon = null;
   80   
   81   
   82       protected ClassLoader commonLoader = null;
   83       protected ClassLoader catalinaLoader = null;
   84       protected ClassLoader sharedLoader = null;
   85   
   86   
   87       // -------------------------------------------------------- Private Methods
   88   
   89   
   90       private void initClassLoaders() {
   91           try {
   92               commonLoader = createClassLoader("common", null);
   93               if( commonLoader == null ) {
   94                   // no config file, default to this loader - we might be in a 'single' env.
   95                   commonLoader=this.getClass().getClassLoader();
   96               }
   97               catalinaLoader = createClassLoader("server", commonLoader);
   98               sharedLoader = createClassLoader("shared", commonLoader);
   99           } catch (Throwable t) {
  100               log.error("Class loader creation threw exception", t);
  101               System.exit(1);
  102           }
  103       }
  104   
  105   
  106       private ClassLoader createClassLoader(String name, ClassLoader parent)
  107           throws Exception {
  108   
  109           String value = CatalinaProperties.getProperty(name + ".loader");
  110           if ((value == null) || (value.equals("")))
  111               return parent;
  112   
  113           ArrayList repositoryLocations = new ArrayList();
  114           ArrayList repositoryTypes = new ArrayList();
  115           int i;
  116    
  117           StringTokenizer tokenizer = new StringTokenizer(value, ",");
  118           while (tokenizer.hasMoreElements()) {
  119               String repository = tokenizer.nextToken();
  120   
  121               // Local repository
  122               boolean replace = false;
  123               String before = repository;
  124               while ((i=repository.indexOf(CATALINA_HOME_TOKEN))>=0) {
  125                   replace=true;
  126                   if (i>0) {
  127                   repository = repository.substring(0,i) + getCatalinaHome() 
  128                       + repository.substring(i+CATALINA_HOME_TOKEN.length());
  129                   } else {
  130                       repository = getCatalinaHome() 
  131                           + repository.substring(CATALINA_HOME_TOKEN.length());
  132                   }
  133               }
  134               while ((i=repository.indexOf(CATALINA_BASE_TOKEN))>=0) {
  135                   replace=true;
  136                   if (i>0) {
  137                   repository = repository.substring(0,i) + getCatalinaBase() 
  138                       + repository.substring(i+CATALINA_BASE_TOKEN.length());
  139                   } else {
  140                       repository = getCatalinaBase() 
  141                           + repository.substring(CATALINA_BASE_TOKEN.length());
  142                   }
  143               }
  144               if (replace && log.isDebugEnabled())
  145                   log.debug("Expanded " + before + " to " + repository);
  146   
  147               // Check for a JAR URL repository
  148               try {
  149                   URL url=new URL(repository);
  150                   repositoryLocations.add(repository);
  151                   repositoryTypes.add(ClassLoaderFactory.IS_URL);
  152                   continue;
  153               } catch (MalformedURLException e) {
  154                   // Ignore
  155               }
  156   
  157               if (repository.endsWith("*.jar")) {
  158                   repository = repository.substring
  159                       (0, repository.length() - "*.jar".length());
  160                   repositoryLocations.add(repository);
  161                   repositoryTypes.add(ClassLoaderFactory.IS_GLOB);
  162               } else if (repository.endsWith(".jar")) {
  163                   repositoryLocations.add(repository);
  164                   repositoryTypes.add(ClassLoaderFactory.IS_JAR);
  165               } else {
  166                   repositoryLocations.add(repository);
  167                   repositoryTypes.add(ClassLoaderFactory.IS_DIR);
  168               }
  169           }
  170   
  171           String[] locations = (String[]) repositoryLocations.toArray(new String[0]);
  172           Integer[] types = (Integer[]) repositoryTypes.toArray(new Integer[0]);
  173    
  174           ClassLoader classLoader = ClassLoaderFactory.createClassLoader
  175               (locations, types, parent);
  176   
  177           // Retrieving MBean server
  178           MBeanServer mBeanServer = null;
  179           if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
  180               mBeanServer =
  181                   (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
  182           } else {
  183               mBeanServer = ManagementFactory.getPlatformMBeanServer();
  184           }
  185   
  186           // Register the server classloader
  187           ObjectName objectName =
  188               new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
  189           mBeanServer.registerMBean(classLoader, objectName);
  190   
  191           return classLoader;
  192   
  193       }
  194   
  195   
  196       /**
  197        * Initialize daemon.
  198        */
  199       public void init()
  200           throws Exception
  201       {
  202   
  203           // Set Catalina path
  204           setCatalinaHome();
  205           setCatalinaBase();
  206   
  207           initClassLoaders();
  208   
  209           Thread.currentThread().setContextClassLoader(catalinaLoader);
  210   
  211           SecurityClassLoad.securityClassLoad(catalinaLoader);
  212   
  213           // Load our startup class and call its process() method
  214           if (log.isDebugEnabled())
  215               log.debug("Loading startup class");
  216           Class startupClass =
  217               catalinaLoader.loadClass
  218               ("org.apache.catalina.startup.Catalina");
  219           Object startupInstance = startupClass.newInstance();
  220   
  221           // Set the shared extensions class loader
  222           if (log.isDebugEnabled())
  223               log.debug("Setting startup class properties");
  224           String methodName = "setParentClassLoader";
  225           Class paramTypes[] = new Class[1];
  226           paramTypes[0] = Class.forName("java.lang.ClassLoader");
  227           Object paramValues[] = new Object[1];
  228           paramValues[0] = sharedLoader;
  229           Method method =
  230               startupInstance.getClass().getMethod(methodName, paramTypes);
  231           method.invoke(startupInstance, paramValues);
  232   
  233           catalinaDaemon = startupInstance;
  234   
  235       }
  236   
  237   
  238       /**
  239        * Load daemon.
  240        */
  241       private void load(String[] arguments)
  242           throws Exception {
  243   
  244           // Call the load() method
  245           String methodName = "load";
  246           Object param[];
  247           Class paramTypes[];
  248           if (arguments==null || arguments.length==0) {
  249               paramTypes = null;
  250               param = null;
  251           } else {
  252               paramTypes = new Class[1];
  253               paramTypes[0] = arguments.getClass();
  254               param = new Object[1];
  255               param[0] = arguments;
  256           }
  257           Method method = 
  258               catalinaDaemon.getClass().getMethod(methodName, paramTypes);
  259           if (log.isDebugEnabled())
  260               log.debug("Calling startup class " + method);
  261           method.invoke(catalinaDaemon, param);
  262   
  263       }
  264   
  265   
  266       // ----------------------------------------------------------- Main Program
  267   
  268   
  269       /**
  270        * Load the Catalina daemon.
  271        */
  272       public void init(String[] arguments)
  273           throws Exception {
  274   
  275           init();
  276           load(arguments);
  277   
  278       }
  279   
  280   
  281       /**
  282        * Start the Catalina daemon.
  283        */
  284       public void start()
  285           throws Exception {
  286           if( catalinaDaemon==null ) init();
  287   
  288           Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null);
  289           method.invoke(catalinaDaemon, (Object [])null);
  290   
  291       }
  292   
  293   
  294       /**
  295        * Stop the Catalina Daemon.
  296        */
  297       public void stop()
  298           throws Exception {
  299   
  300           Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null);
  301           method.invoke(catalinaDaemon, (Object [] ) null);
  302   
  303       }
  304   
  305   
  306       /**
  307        * Stop the standlone server.
  308        */
  309       public void stopServer()
  310           throws Exception {
  311   
  312           Method method = 
  313               catalinaDaemon.getClass().getMethod("stopServer", (Class []) null);
  314           method.invoke(catalinaDaemon, (Object []) null);
  315   
  316       }
  317   
  318   
  319      /**
  320        * Stop the standlone server.
  321        */
  322       public void stopServer(String[] arguments)
  323           throws Exception {
  324   
  325           Object param[];
  326           Class paramTypes[];
  327           if (arguments==null || arguments.length==0) {
  328               paramTypes = null;
  329               param = null;
  330           } else {
  331               paramTypes = new Class[1];
  332               paramTypes[0] = arguments.getClass();
  333               param = new Object[1];
  334               param[0] = arguments;
  335           }
  336           Method method = 
  337               catalinaDaemon.getClass().getMethod("stopServer", paramTypes);
  338           method.invoke(catalinaDaemon, param);
  339   
  340       }
  341   
  342   
  343       /**
  344        * Set flag.
  345        */
  346       public void setAwait(boolean await)
  347           throws Exception {
  348   
  349           Class paramTypes[] = new Class[1];
  350           paramTypes[0] = Boolean.TYPE;
  351           Object paramValues[] = new Object[1];
  352           paramValues[0] = new Boolean(await);
  353           Method method = 
  354               catalinaDaemon.getClass().getMethod("setAwait", paramTypes);
  355           method.invoke(catalinaDaemon, paramValues);
  356   
  357       }
  358   
  359       public boolean getAwait()
  360           throws Exception
  361       {
  362           Class paramTypes[] = new Class[0];
  363           Object paramValues[] = new Object[0];
  364           Method method =
  365               catalinaDaemon.getClass().getMethod("getAwait", paramTypes);
  366           Boolean b=(Boolean)method.invoke(catalinaDaemon, paramValues);
  367           return b.booleanValue();
  368       }
  369   
  370   
  371       /**
  372        * Destroy the Catalina Daemon.
  373        */
  374       public void destroy() {
  375   
  376           // FIXME
  377   
  378       }
  379   
  380   
  381       /**
  382        * Main method, used for testing only.
  383        *
  384        * @param args Command line arguments to be processed
  385        */
  386       public static void main(String args[]) {
  387   
  388           if (daemon == null) {
  389               daemon = new Bootstrap();
  390               try {
  391                   daemon.init();
  392               } catch (Throwable t) {
  393                   t.printStackTrace();
  394                   return;
  395               }
  396           }
  397   
  398           try {
  399               String command = "start";
  400               if (args.length > 0) {
  401                   command = args[args.length - 1];
  402               }
  403   
  404               if (command.equals("startd")) {
  405                   args[args.length - 1] = "start";
  406                   daemon.load(args);
  407                   daemon.start();
  408               } else if (command.equals("stopd")) {
  409                   args[args.length - 1] = "stop";
  410                   daemon.stop();
  411               } else if (command.equals("start")) {
  412                   daemon.setAwait(true);
  413                   daemon.load(args);
  414                   daemon.start();
  415               } else if (command.equals("stop")) {
  416                   daemon.stopServer(args);
  417               } else {
  418                   log.warn("Bootstrap: command \"" + command + "\" does not exist.");
  419               }
  420           } catch (Throwable t) {
  421               t.printStackTrace();
  422           }
  423   
  424       }
  425   
  426       public void setCatalinaHome(String s) {
  427           System.setProperty( "catalina.home", s );
  428       }
  429   
  430       public void setCatalinaBase(String s) {
  431           System.setProperty( "catalina.base", s );
  432       }
  433   
  434   
  435       /**
  436        * Set the <code>catalina.base</code> System property to the current
  437        * working directory if it has not been set.
  438        */
  439       private void setCatalinaBase() {
  440   
  441           if (System.getProperty("catalina.base") != null)
  442               return;
  443           if (System.getProperty("catalina.home") != null)
  444               System.setProperty("catalina.base",
  445                                  System.getProperty("catalina.home"));
  446           else
  447               System.setProperty("catalina.base",
  448                                  System.getProperty("user.dir"));
  449   
  450       }
  451   
  452   
  453       /**
  454        * Set the <code>catalina.home</code> System property to the current
  455        * working directory if it has not been set.
  456        */
  457       private void setCatalinaHome() {
  458   
  459           if (System.getProperty("catalina.home") != null)
  460               return;
  461           File bootstrapJar = 
  462               new File(System.getProperty("user.dir"), "bootstrap.jar");
  463           if (bootstrapJar.exists()) {
  464               try {
  465                   System.setProperty
  466                       ("catalina.home", 
  467                        (new File(System.getProperty("user.dir"), ".."))
  468                        .getCanonicalPath());
  469               } catch (Exception e) {
  470                   // Ignore
  471                   System.setProperty("catalina.home",
  472                                      System.getProperty("user.dir"));
  473               }
  474           } else {
  475               System.setProperty("catalina.home",
  476                                  System.getProperty("user.dir"));
  477           }
  478   
  479       }
  480   
  481   
  482       /**
  483        * Get the value of the catalina.home environment variable.
  484        */
  485       public static String getCatalinaHome() {
  486           return System.getProperty("catalina.home",
  487                                     System.getProperty("user.dir"));
  488       }
  489   
  490   
  491       /**
  492        * Get the value of the catalina.base environment variable.
  493        */
  494       public static String getCatalinaBase() {
  495           return System.getProperty("catalina.base", getCatalinaHome());
  496       }
  497   
  498   
  499   }

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