zoukankan      html  css  js  c++  java
  • (三)Bootstrap.jar

    catalina.bat 在最后启动了bootstrap.jar, 传递了start作为参数(如果多个参数的话,start在尾部)。 然后org.apache.catalina.startup.Bootstrap的main方法初始化了一个bootstrap守护进程,通过调用了catalina.java对应方法。

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

    /*

     * Licensed to the Apache Software Foundation (ASF) under one or more

     * contributor license agreements.  See the NOTICE file distributed with

     * this work for additional information regarding copyright ownership.

     * The ASF licenses this file to You under the Apache License, Version 2.0

     * (the "License"); you may not use this file except in compliance with

     * the License.  You may obtain a copy of the License at

     *

     *      http://www.apache.org/licenses/LICENSE-2.0

     *

     * Unless required by applicable law or agreed to in writing, software

     * distributed under the License is distributed on an "AS IS" BASIS,

     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

     * See the License for the specific language governing permissions and

     * limitations under the License.

     */

    package org.apache.catalina.startup;

    import java.io.File;

    import java.lang.reflect.InvocationTargetException;

    import java.lang.reflect.Method;

    import java.net.MalformedURLException;

    import java.net.URL;

    import java.util.ArrayList;

    import java.util.List;

    import java.util.StringTokenizer;

    import org.apache.catalina.Globals;

    import org.apache.catalina.security.SecurityClassLoad;

    import org.apache.catalina.startup.ClassLoaderFactory.Repository;

    import org.apache.catalina.startup.ClassLoaderFactory.RepositoryType;

    import org.apache.juli.logging.Log;

    import org.apache.juli.logging.LogFactory;

    /**

     * Bootstrap loader for Catalina.  This application constructs a class loader

     * for use in loading the Catalina internal classes (by accumulating all of the

     * JAR files found in the "server" directory under "catalina.home"), and

     * starts the regular execution of the container.  The purpose of this

     * roundabout approach is to keep the Catalina internal classes (and any

     * other classes they depend on, such as an XML parser) out of the system

     * class path and therefore not visible to application level classes.

     * 

     * @author Craig R. McClanahan

     * @author Remy Maucherat

     */

    // Catalina的Bootstrap加载器。这个应用为加载Catalina的内部类(通过累加“catalina.home”下的jar文件)构造了一个类加载器,并启动了容器。

    // 这种间接做法的目的是使catalina的内部类(和它依赖的其他类,必须Xml转化器)与系统的class path分离,与应用级别的类互相不能访问。

    public final class Bootstrap {

        private static final Log log = LogFactory.getLog(Bootstrap.class);

        // ------------------------------------------------------- Static Variables

        /**

         * Daemon object used by main.

         */

        private static Bootstrap daemon = null;

        // -------------------------------------------------------------- Variables

        /**

         * Daemon reference.

         */

        private Object catalinaDaemon = null;

        ClassLoader commonLoader = null;

        ClassLoader catalinaLoader = null;

        ClassLoader sharedLoader = null;

        // -------------------------------------------------------- Private Methods

        private void initClassLoaders() {

            try {

                commonLoader = createClassLoader("common", null);

                if( commonLoader == null ) {

                    // no config file, default to this loader - we might be in a 'single' env.

                    commonLoader=this.getClass().getClassLoader();

                }

                catalinaLoader = createClassLoader("server", commonLoader); // 在tomcat 7x的catalina.properties中server.loader为空

                sharedLoader = createClassLoader("shared", commonLoader); // 在tomcat 7x的catalina.properties中shared.loader为空

            } catch (Throwable t) {

                handleThrowable(t);

                log.error("Class loader creation threw exception", t);

                System.exit(1);

            }

        }

       // 如果配置文件中没有name+".loader"属性, 返回parent

        private ClassLoader createClassLoader(String name, ClassLoader parent)

            throws Exception {

            String value = CatalinaProperties.getProperty(name + ".loader");

            if ((value == null) || (value.equals("")))

                return parent;

            value = replace(value); // 替换catalina.home和catalina.base

            List<Repository> repositories = new ArrayList<Repository>();

            StringTokenizer tokenizer = new StringTokenizer(value, ","); // 处理value把结尾不同的值放进不同的Repository

            while (tokenizer.hasMoreElements()) {

                String repository = tokenizer.nextToken().trim();

                if (repository.length() == 0) {

                    continue;

                }

                // Check for a JAR URL repository

                try {

                    @SuppressWarnings("unused")

                    URL url = new URL(repository);

                    repositories.add(

                            new Repository(repository, RepositoryType.URL));

                    continue;

                } catch (MalformedURLException e) {

                    // Ignore

                }

                // Local repository

                if (repository.endsWith("*.jar")) {

                    repository = repository.substring

                        (0, repository.length() - "*.jar".length());

                    repositories.add(

                            new Repository(repository, RepositoryType.GLOB));

                } else if (repository.endsWith(".jar")) {

                    repositories.add(

                            new Repository(repository, RepositoryType.JAR));

                } else {

                    repositories.add(

                            new Repository(repository, RepositoryType.DIR));

                }

            }

            return ClassLoaderFactory.createClassLoader(repositories, parent); // 特权化

        }

        /**

         * System property replacement in the given string.

         * 

         * @param str The original string

         * @return the modified string

         */

        protected String replace(String str) {

            // Implementation is copied from ClassLoaderLogManager.replace(),

            // but added special processing for catalina.home and catalina.base.

            String result = str;

            int pos_start = str.indexOf("${");

            if (pos_start >= 0) {

                StringBuilder builder = new StringBuilder();

                int pos_end = -1;

                while (pos_start >= 0) {

                    builder.append(str, pos_end + 1, pos_start);

                    pos_end = str.indexOf('}', pos_start + 2);

                    if (pos_end < 0) {

                        pos_end = pos_start - 1;

                        break;

                    }

                    String propName = str.substring(pos_start + 2, pos_end);

                    String replacement;

                    if (propName.length() == 0) {

                        replacement = null;

                    } else if (Globals.CATALINA_HOME_PROP.equals(propName)) {

                        replacement = getCatalinaHome();

                    } else if (Globals.CATALINA_BASE_PROP.equals(propName)) {

                        replacement = getCatalinaBase();

                    } else {

                        replacement = System.getProperty(propName);

                    }

                    if (replacement != null) {

                        builder.append(replacement);

                    } else {

                        builder.append(str, pos_start, pos_end + 1);

                    }

                    pos_start = str.indexOf("${", pos_end + 1);

                }

                builder.append(str, pos_end + 1, str.length());

                result = builder.toString();

            }

            return result;

        }

        /**

         * Initialize daemon.

         */

        public void init()

            throws Exception

        {

            // Set Catalina path

            setCatalinaHome(); // 设置catalina.home, 在catalina.bat启动Bootstarp.java时通过-Dcatalina.home传入; 没有就重新设置

            setCatalinaBase(); // 设置catalina.base, 在catalina.bat启动Bootstarp.java时通过-Dcatalina.base传入; 没有就重新设置

            initClassLoaders(); // 使用catalina.properties初始化了3个ClassLoader, 在tomcat7x中catalina.loader和server.loader为空;

                                // 所以catalinaLoader = commonLoader; sharedLoader = commonLoader;

                                // commonLoader没有parent classLoader, catalinaLoader和sharedLoader的parent classLoader是commonLoader

            Thread.currentThread().setContextClassLoader(catalinaLoader);

            SecurityClassLoad.securityClassLoad(catalinaLoader);

            // Load our startup class and call its process() method

            if (log.isDebugEnabled())

                log.debug("Loading startup class");

            Class<?> startupClass =

                catalinaLoader.loadClass

                ("org.apache.catalina.startup.Catalina");

            Object startupInstance = startupClass.newInstance();

            // Set the shared extensions class loader

            if (log.isDebugEnabled())

                log.debug("Setting startup class properties");

            String methodName = "setParentClassLoader";

            Class<?> paramTypes[] = new Class[1];

            paramTypes[0] = Class.forName("java.lang.ClassLoader");

            Object paramValues[] = new Object[1];

            paramValues[0] = sharedLoader;

            Method method =

                startupInstance.getClass().getMethod(methodName, paramTypes);

            method.invoke(startupInstance, paramValues); // 调用Catalina.setParentClassLoader(), sharedLoader作为参数, 参数类型是ClassLoader

            catalinaDaemon = startupInstance; // catalina守护进程

        }

        /**

         * Load daemon.

         */

        private void load(String[] arguments)

            throws Exception {

            // Call the load() method

            String methodName = "load";

            Object param[];

            Class<?> paramTypes[];

            if (arguments==null || arguments.length==0) {

                paramTypes = null;

                param = null;

            } else {

                paramTypes = new Class[1];

                paramTypes[0] = arguments.getClass();

                param = new Object[1];

                param[0] = arguments;

            }

            Method method =

                catalinaDaemon.getClass().getMethod(methodName, paramTypes);

            if (log.isDebugEnabled())

                log.debug("Calling startup class " + method);

            method.invoke(catalinaDaemon, param); // catalina.java 下有俩个load方法, 一个有参一个无参

        }

        /**

         * getServer() for configtest

         */

        private Object getServer() throws Exception {

            String methodName = "getServer";

            Method method =

                catalinaDaemon.getClass().getMethod(methodName);

            return method.invoke(catalinaDaemon);

        }

        // ----------------------------------------------------------- Main Program

        /**

         * Load the Catalina daemon.

         */

        public void init(String[] arguments)

            throws Exception {

            init();

            load(arguments);

        }

        /**

         * Start the Catalina daemon.

         */

        public void start()

            throws Exception {

            if( catalinaDaemon==null ) init();

            Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null);

            method.invoke(catalinaDaemon, (Object [])null);

        }

        /**

         * Stop the Catalina Daemon.

         */

        public void stop()

            throws Exception {

            Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null);

            method.invoke(catalinaDaemon, (Object [] ) null);

        }

        /**

         * Stop the standalone server.

         */

        public void stopServer()

            throws Exception {

            Method method =

                catalinaDaemon.getClass().getMethod("stopServer", (Class []) null);

            method.invoke(catalinaDaemon, (Object []) null);

        }

       /**

         * Stop the standalone server.

         */

        public void stopServer(String[] arguments)

            throws Exception {

            Object param[];

            Class<?> paramTypes[];

            if (arguments==null || arguments.length==0) {

                paramTypes = null;

                param = null;

            } else {

                paramTypes = new Class[1];

                paramTypes[0] = arguments.getClass();

                param = new Object[1];

                param[0] = arguments;

            }

            Method method =

                catalinaDaemon.getClass().getMethod("stopServer", paramTypes);

            method.invoke(catalinaDaemon, param);

        }

        /**

         * Set flag.

         */

        public void setAwait(boolean await)

            throws Exception {

            Class<?> paramTypes[] = new Class[1];

            paramTypes[0] = Boolean.TYPE;

            Object paramValues[] = new Object[1];

            paramValues[0] = Boolean.valueOf(await);

            Method method =

                catalinaDaemon.getClass().getMethod("setAwait", paramTypes);

            method.invoke(catalinaDaemon, paramValues);

        }

        public boolean getAwait()

            throws Exception

        {

            Class<?> paramTypes[] = new Class[0];

            Object paramValues[] = new Object[0];

            Method method =

                catalinaDaemon.getClass().getMethod("getAwait", paramTypes);

            Boolean b=(Boolean)method.invoke(catalinaDaemon, paramValues);

            return b.booleanValue();

        }

        /**

         * Destroy the Catalina Daemon.

         */

        public void destroy() {

            // FIXME

        }

        /**

         * Main method and entry point when starting Tomcat via the provided

         * scripts.

         *

         * @param args Command line arguments to be processed

         */

        public static void main(String args[]) {

            if (daemon == null) { // stop时不为空

                // Don't set daemon until init() has completed

                Bootstrap bootstrap = new Bootstrap();

                try {

                    bootstrap.init(); // 执行init()

                } catch (Throwable t) {

                    handleThrowable(t);

                    t.printStackTrace();

                    return;

                }

                daemon = bootstrap; // 守护进程

            } else {

                // When running as a service the call to stop will be on a new

                // thread so make sure the correct class loader is used to prevent

                // a range of class not found exceptions.

                Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);

            }

            try { // catalina.bat把start作为最后一个参数启动

                String command = "start";

                if (args.length > 0) {

                    command = args[args.length - 1];

                }

                // 根据不同参数, 调用catalina.java中的同名方法; command = startd或start或onfigtest时, 先通过反射调用catalina.load方法

                if (command.equals("startd")) {

                    args[args.length - 1] = "start";

                    daemon.load(args);

                    daemon.start();

                } else if (command.equals("stopd")) {

                    args[args.length - 1] = "stop";

                    daemon.stop();

                } else if (command.equals("start")) {

                    daemon.setAwait(true);

                    daemon.load(args);

                    daemon.start();

                } else if (command.equals("stop")) {

                    daemon.stopServer(args);

                } else if (command.equals("configtest")) {

                    daemon.load(args);

                    if (null==daemon.getServer()) {

                        System.exit(1);

                    }

                    System.exit(0);

                } else {

                    log.warn("Bootstrap: command "" + command + "" does not exist.");

                }

            } catch (Throwable t) {

                // Unwrap the Exception for clearer error reporting

                if (t instanceof InvocationTargetException &&

                        t.getCause() != null) {

                    t = t.getCause();

                }

                handleThrowable(t);

                t.printStackTrace();

                System.exit(1);

            }

        }

        public void setCatalinaHome(String s) {

            System.setProperty(Globals.CATALINA_HOME_PROP, s);

        }

        public void setCatalinaBase(String s) {

            System.setProperty(Globals.CATALINA_BASE_PROP, s);

        }

        /**

         * Set the <code>catalina.base</code> System property to the current

         * working directory if it has not been set.

         */

        private void setCatalinaBase() {

            if (System.getProperty(Globals.CATALINA_BASE_PROP) != null)

                return;

            if (System.getProperty(Globals.CATALINA_HOME_PROP) != null)

                System.setProperty(Globals.CATALINA_BASE_PROP,

                                   System.getProperty(Globals.CATALINA_HOME_PROP));

            else

                System.setProperty(Globals.CATALINA_BASE_PROP,

                                   System.getProperty("user.dir"));

        }

        /**

         * Set the <code>catalina.home</code> System property to the current

         * working directory if it has not been set.

         */

        private void setCatalinaHome() {

            if (System.getProperty(Globals.CATALINA_HOME_PROP) != null)

                return;

            File bootstrapJar =

                new File(System.getProperty("user.dir"), "bootstrap.jar");

            if (bootstrapJar.exists()) {

                try {

                    System.setProperty // 设置catalina.home为user.dir的父目录

                        (Globals.CATALINA_HOME_PROP,

                         (new File(System.getProperty("user.dir"), ".."))

                         .getCanonicalPath());

                } catch (Exception e) {

                    // Ignore

                    System.setProperty(Globals.CATALINA_HOME_PROP,

                                       System.getProperty("user.dir"));

                }

            } else {

                System.setProperty(Globals.CATALINA_HOME_PROP,

                                   System.getProperty("user.dir"));

            }

        }

        /**

         * Get the value of the catalina.home environment variable.

         */

        public static String getCatalinaHome() {

            return System.getProperty(Globals.CATALINA_HOME_PROP,

                                      System.getProperty("user.dir"));

        }

        /**

         * Get the value of the catalina.base environment variable.

         */

        public static String getCatalinaBase() {

            return System.getProperty(Globals.CATALINA_BASE_PROP, getCatalinaHome());

        }

        // Copied from ExceptionUtils since that class is not visible during start

        private static void handleThrowable(Throwable t) {

            if (t instanceof ThreadDeath) {

                throw (ThreadDeath) t;

            }

            if (t instanceof VirtualMachineError) {

                throw (VirtualMachineError) t;

            }

            // All other instances of Throwable will be silently swallowed

        }

    }

  • 相关阅读:
    算法初步-插入排序
    [数据结构]之栈
    [数据结构]之队列
    [数据结构]之链表
    [数据结构]之顺序表
    SDL一环境配置
    三大框架结构的原理及其优点
    hibernate----hibernate的基础设置
    其他
    struts----用Action的属性接收参数
  • 原文地址:https://www.cnblogs.com/yizhishi/p/5952119.html
Copyright © 2011-2022 走看看