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

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