<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    The NoteBook of EricKong

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

          JVM在運(yùn)行時(shí)會(huì)產(chǎn)生三個(gè)ClassLoader,Bootstrap ClassLoaderExtension ClassLoaderAppClassLoader.其中,Bootstrap是用C++編寫的,我們?cè)贘ava中看不到它,是null。它用來加載核心類庫(kù),在JVM源代碼中這樣寫道:
    static const char classpathFormat[] =
    "%/lib/rt.jar:"
    "%/lib/i18n.jar:"
    "%/lib/sunrsasign.jar:"
    "%/lib/jsse.jar:"
    "%/lib/jce.jar:"
    "%/lib/charsets.jar:"
    "%/classes";
          知道為什么不需要在classpath中加載這些類了吧?人家在JVM啟動(dòng)的時(shí)候就自動(dòng)加載了,并且在運(yùn)行過程中根本不能修改Bootstrap加載路徑。Extension ClassLoader用來加載擴(kuò)展類,即/lib/ext中的類。最后AppClassLoader才是加載Classpath的。
          ClassLoader加載類用的是委托模型。即先讓Parent類(而不是Super,不是繼承關(guān)系)尋找,Parent找不到才自己找??磥鞢lassLoader還是蠻孝順的。三者的關(guān)系為:AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent為Bootstrap ClassLoader。加載一個(gè)類時(shí),首先BootStrap先進(jìn)行尋找,找不到再由ExtClassLoader尋找,最后才是AppClassLoader。
         為什么要設(shè)計(jì)的這么復(fù)雜呢?其中一個(gè)重要原因就是安全性。比如在Applet中,如果編寫了一個(gè)java.lang.String類并具有破壞性。假如不采用這種委托機(jī)制,就會(huì)將這個(gè)具有破壞性的String加載到了用戶機(jī)器上,導(dǎo)致破壞用戶安全。但采用這種委托機(jī)制則不會(huì)出現(xiàn)這種情況。因?yàn)橐虞djava.lang.String類時(shí),系統(tǒng)最終會(huì)由Bootstrap進(jìn)行加載,這個(gè)具有破壞性的String永遠(yuǎn)沒有機(jī)會(huì)加載。
    我們來看這段代碼:

    //A.java
    public class A{
        
    public static void main(String[] args){
            A a
    =new A();
            System.out.println(System.getProperty(
    "java.ext.dirs"));
            System.out.println(a.getClass().getClassLoader());
            B b
    =new B();
            b.print();
        }

    }

    //B.java
    public class B{
        
    public void print(){
            System.out.println(
    this.getClass().getClassLoader());
        }

    }

    1、我們將它放在Classpath中,則打印出
    sun.misc.Launcher$AppClassLoader@92e78c
    sun.misc.Launcher$AppClassLoader@92e78c
    可見都是由AppClassLoader來加載的。
    2
    、我們將其放在%jre%/lib/ext/classes(ExtClassLoader的加載目錄。其加載/lib/ext中的jar文件或者子目錄classes中的class文件)中。則會(huì)打印出:
    sun.misc.Launcher$ExtClassLoader
    sun.misc.Launcher$ExtClassLoader
    3
    、我們將A.class放到%jre%/lib/ext/classes中,而將B.class放到classpaht中又會(huì)怎么樣呢?結(jié)果是:
    sun.misc.Launcher$ExtClassLoader
    Exception in thread "main" java.lang.NoClassDefFoundError:B
        at A.main(A.java:6)
    怎么會(huì)這樣呢?這其中有一個(gè)重要的問題:A類當(dāng)然是由ExtClassLoader來加載的,B類要由哪個(gè)加載呢?B類要由調(diào)用它自己的類的類加載器(真拗口)。也就是說,A調(diào)用了B,所以BA的類加載器ExtClassLoader來加載。ExtClassLoader根據(jù)委托機(jī)制,先拜托Bootstrap加載,Bootstrap沒有找到。然后它再自己尋找B類,還是沒找到,所以拋出異常。ExtClassLoader不會(huì)請(qǐng)求AppClassLoader來加載!你可能會(huì)想:這算什么問題,我把兩個(gè)類放到一起不就行了?
        呵呵,沒這么簡(jiǎn)單。比如JDBC是核心類庫(kù),而各個(gè)數(shù)據(jù)庫(kù)的JDBC驅(qū)動(dòng)則是擴(kuò)展類庫(kù)或在classpath中定義的。所以JDBCBootstrap ClassLoader加載,而驅(qū)動(dòng)要由AppClassLoader加載。等等,問題來了,Bootstrap不會(huì)請(qǐng)求AppClassLoader加載類啊。那么,他們?cè)趺磳?shí)現(xiàn)的呢?我就涉及到一個(gè)Context ClassLoader的問題,調(diào)用Thread.getContextClassLoader

    1 - Tomcat的類載入器的結(jié)構(gòu)

    Tomcat Server在啟動(dòng)的時(shí)候?qū)?gòu)造一個(gè)ClassLoader樹,以保證模塊的類庫(kù)是私有的
    Tomcat Server的ClassLoader結(jié)構(gòu)如下:

            +-----------------------------+
            |         Bootstrap           |
            |             |               |
            |          System             |
            |             |               |
            |          Common             |
            |         /      \            |
            |     Catalina Shared        |
            |               /    \        |
            |          WebApp1 WebApp2   |
            +-----------------------------+

    其中:
    - Bootstrap -
    載入JVM自帶的類和$JAVA_HOME/jre/lib/ext/*.jar
    - System     -
    載入$CLASSPATH/*.class
    - Common   -
    載入$CATALINA_HOME/common/...,它們對(duì)TOMCAT和所有的WEB APP都可見
    - Catalina    -
    載入$CATALINA_HOME/server/...,  它們僅對(duì)TOMCAT可見,對(duì)所有的WEB APP都不可見
    - Shared      -
    載入$CATALINA_HOME/shared/..., 它們僅對(duì)所有WEB APP可見,對(duì)TOMCAT不可見(也不必見)
    - WebApp    - 
    載入ContextBase/WEB-INF/...,    它們僅對(duì)該WEB APP可見

     
    2 - ClassLoader的工作原理 
          每個(gè)運(yùn)行中的線程都有一個(gè)成員contextClassLoader,用來在運(yùn)行時(shí)動(dòng)態(tài)地載入其它類系統(tǒng)默認(rèn)的contextClassLoader是systemClassLoader,所以一般而言java程序在執(zhí)行時(shí)可以使用JVM自帶的類、$JAVA_HOME/jre/lib/ext/中的類和$CLASSPATH/中的類可以使用Thread.currentThread().setContextClassLoader(...);更改當(dāng)前線程的contextClassLoader,來改變其載入類的行為ClassLoader被組織成樹形,一般的工作原理是:
    1) 線程需要用到某個(gè)類,于是contextClassLoader被請(qǐng)求來載入該類
    2) contextClassLoader請(qǐng)求它的父ClassLoader來完成該載入請(qǐng)求
    3) 如果父ClassLoader無(wú)法載入類,則contextClassLoader試圖自己來載入
        注意:WebApp ClassLoader的工作原理和上述有少許不同:
        它先試圖自己載入類(在ContextBase/WEB-INF/...中載入類),如果無(wú)法載入,再請(qǐng)求父ClassLoader完成
    由此可得:
        - 對(duì)于WEB APP線程,它的contextClassLoader是WebApp ClassLoader
        - 對(duì)于Tomcat Server線程,它的contextClassLoader是CatalinaClassLoader


    3 - 部分原代碼分析
     
    3.1 - org/apache/catalina/startup/Bootstrap.java
    Tomcat Server線程的起點(diǎn)
    構(gòu)造ClassLoader樹,并設(shè)置Tomcat Server線程的contextClassLoader為catalinaloader
    載入若干類,然后轉(zhuǎn)入org.apache.catalina.startup.Catalina類中
    package org.apache.catalina.startup;

     

    // JDK類庫(kù)
    import java.io.File;
    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.ArrayList;

    //apache自己的類庫(kù)
    import org.apache.catalina.loader.Extension;
    import org.apache.catalina.loader.StandardClassLoader;



    /**
     * Boostrap 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
     * 
    @version $Revision: 1.36 $ $Date: 2002/04/01 19:51:31 $
     
    */


    /**
     * 該類的main方法的主要任務(wù):
     * --------------------------
     *
     * 1,創(chuàng)建TOMCAT自己的類載入器(ClassLoader)
     *      +---------------------------+
     *      |         Bootstrap         |
     *      |             |             |
     *      |          System           |
     *      |             |             |
     *      |          Common           |
     *      |         /      \          |
     *      |     Catalina  Shared      |
     *      +---------------------------+
     *    其中:
     *    - Bootstrap - 載入JVM自帶的類和$JAVA_HOME/jre/lib/ext/*.jar
     *    - System    - 載入$CLASSPATH/*.class
     *    - Common    - 載入$CATALINA_HOME/common/,它們對(duì)TOMCAT和所有的WEB APP都可見
     *    - Catalina  - 載入$CATALINA_HOME/server/,它們僅對(duì)TOMCAT可見,對(duì)所有的WEB APP都不可見
     *    - Shared    - 載入$CATALINA_HOME/shared/,它們僅對(duì)所有WEB APP可見,對(duì)TOMCAT不可見(也不必見)
     *    注意:當(dāng)一個(gè)ClassLoader被請(qǐng)求載入一個(gè)類時(shí),它首先請(qǐng)求其父ClassLoader完成載入,
     *    僅當(dāng)其父ClassLoader無(wú)法載入該類時(shí),才試圖自己載入該類
     * 2,改變本身線程的默認(rèn)ClassLoader(本線程就是Tomcat Server線程,類載入器是catalinaLoader)
     * 3,讓catalinaLoader載入一些類,類的位置在$CATALINA_HOME/server/lib/catalina.jar中
     * 4,創(chuàng)建org.apache.catalina.startup.Catalina類的一個(gè)實(shí)例startupInstance,并為其調(diào)用方法:
     *    startupInstance.setParentClassLoader(sharedLoader);
     *    startupInstance.process(args);
     *
     *
     * 有關(guān)ClassLoader的說明:
     * -----------------------
     *
     * 每個(gè)被DEPLOY的WEB APP都會(huì)被創(chuàng)建一個(gè)ClassLoader,用來載入該WEB APP自己的類
     * 這些類的位置是webappX/WEB-INF/classes/*.class和webappX/WEB-INF/lib/*.jar
     *
     * ClassLoader的工作流程是:
     * 1) 收到一個(gè)載入類的的請(qǐng)求
     * 2) 請(qǐng)求其父ClassLoader來完成該類的載入
     * 3) 如果父ClassLoader無(wú)法載入,則自己試圖完成該類的載入
     *
     * 特別注意WEB APP自己的ClassLoader的實(shí)現(xiàn)與眾不同:
     * 它先試圖從WEB APP自己的目錄里載入,如果失敗則請(qǐng)求父ClassLoader的代理
     * 這樣可以讓不同的WEB APP之間的類載入互不干擾
     *
     * WEB APP的ClassLoader的層次結(jié)構(gòu)是:
     *     +----------------------------+
     *     |       Shared               |
     *     |      /      \           |
     *     |   Webapp1  Webapp2      |
     *     +----------------------------+
     * 故對(duì)于一個(gè)WEB APP,其類載入的優(yōu)先順序如下:
     * - /WEB-INF/classes/*.class 和 /WEB-INF/lib/*.jar
     * - Bootstrap classes of JVM
     * - System class loader classes
     * - $CATALINA_HOME/common/
     * - $CATALINA_HOME/shared/
     *
     *
     * 小結(jié):
     * ------
     *
     * 綜上分析
     * - Tomcat Server線程使用的classLoader是Catalina
     * - 每個(gè)WEB APP線程使用的classloader是Webapp?
     *
     
    */



    public final class Bootstrap {
        
    /**
         * DEBUG級(jí)別
         
    */

        
    private static int debug = 0;
        
    /**
         * 腳本執(zhí)行該程序時(shí),提供以下的系統(tǒng)屬性:
         * java.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
         * java.security.manager \
         * java.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
         * catalina.base="$CATALINA_BASE" \
         * catalina.home="$CATALINA_HOME" \
         * java.io.tmpdir="$CATALINA_TMPDIR" \
         *
         * 
    @param args Command line arguments to be processed
         
    */

        
    public static void main(String args[]) {
            
    // 設(shè)置debug
            for (int i = 0; i < args.length; i++)  {
                
    if ("-debug".equals(args[i]))
                    debug 
    = 1;
            }

            
    // 設(shè)置好系統(tǒng)屬性catalina.base,即保證其有值
            if (System.getProperty("catalina.base"== null)
                System.setProperty(
    "catalina.base", getCatalinaHome());
            
    // 創(chuàng)建三個(gè)ClassLoader
            
    // 這三個(gè)對(duì)象是通過ClassLoaderFactory的靜態(tài)方法創(chuàng)建的
            
    // 其實(shí)際類型是StandardClassLoader,完成tomcat自定義的類載入
            
    // 這些類對(duì)非tomcat及其上的webapp的其它java程序不可見,故用自己的Classloader載入
            ClassLoader commonLoader = null;
            ClassLoader catalinaLoader 
    = null;
            ClassLoader sharedLoader 
    = null;
            
    try {
                File unpacked[] 
    = new File[1];
                File packed[] 
    = new File[1];
                File packed2[] 
    = new File[2];    
                ClassLoaderFactory.setDebug(debug);


                
    // $CATALINA_HOME/common/classes/*.class - 未壓縮的類
                
    // $CATALINA_HOME/common/endorsed/*.jar - 壓縮的類(endorse:支持)
                
    // $CATALINA_HOME/common/lib/*.jar - 壓縮的類
                
    // 這些類是被tomcat server以及所有的webapp所共享的類,由commonLoader負(fù)責(zé)載入

                unpacked[
    0= new File(getCatalinaHome(),"common" + File.separator + "classes");
                packed2[
    0=  new File(getCatalinaHome(),"common" + File.separator + "endorsed");
                packed2[
    1=  new File(getCatalinaHome(),"common" + File.separator + "lib");
                commonLoader 
    = ClassLoaderFactory.createClassLoader(unpacked, packed2, null);

                
    // $CATALINA_HOME/server/classes/*.class
                
    // $CATALINA_HOME/server/lib/*.jar
                
    // 這些類是僅被tomcat server使用而對(duì)webapp不可見的類,由catalinaLoader負(fù)責(zé)載入

                unpacked[
    0= new File(getCatalinaHome(),"server" + File.separator + "classes");
                packed[
    0]     = new File(getCatalinaHome(),"server" + File.separator + "lib");
                catalinaLoader 
    = ClassLoaderFactory.createClassLoader(unpacked, packed,commonLoader);
     
                
    // $CATALINA_BASE/shared/classes/*.class
                
    // $CATALINA_BASE/shared/lib/*.jar
                
    // 這些類是僅被tomcat的webapp使用的類,由sharedLoader負(fù)責(zé)載入

                unpacked[
    0]  = new File(getCatalinaBase(),"shared" + File.separator + "classes");
                packed[
    0]      = new File(getCatalinaBase(),"shared" + File.separator + "lib");
                sharedLoader 
    = ClassLoaderFactory.createClassLoader(unpacked, packed,commonLoader);
                                                         
                
    // 注意三個(gè)自己定置的ClassLoader的層次關(guān)系:
                
    // systemClassLoader (root)
                
    //   +--- commonLoader
                
    //          +--- catalinaLoader
                
    //          +--- sharedLoader

                        }
     catch (Throwable t) {
                log(
    "Class loader creation threw exception", t);
                System.exit(
    1);

            }


            
    // 為當(dāng)前的線程更改其contextClassLoader
            
    // 一般的線程默認(rèn)的contextClassLoader是系統(tǒng)的ClassLoader(所有其它自定義ClassLoader的父親)
            
    // 當(dāng)該線程需要載入類時(shí),將使用自己的contextClassLoader來尋找并載入類
            
    // 更改contextClassLoader可以更改該線程的尋找和載入類的行為,但不影響到其它線程
            
    // 注意!Tomcat Server線程使用的是catalinaLoader

            Thread.currentThread().setContextClassLoader(catalinaLoader);

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

            
    try {
                
    // 預(yù)載入catalinalLoader的一些類
                SecurityClassLoad.securityClassLoad(catalinaLoader);
                
    // 獲得tomcat的啟動(dòng)類:org.apache.catalina.startup.Catalina,并創(chuàng)建該類的一個(gè)實(shí)例
                if (debug >= 1)
                    log(
    "Loading startup class");
                Class startupClass 
    = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
                Object startupInstance 
    = startupClass.newInstance();


                
    // 設(shè)置startupInstance的父ClassLoader,相當(dāng)于執(zhí)行:
                
    // Catalina startupInstance = new Catailina();
                
    // startupInstance.setParentClassLoader(sharedLoader);
                
    // 詳情參考類org.apache.catalina.startup.Catalina

                
    if (debug >= 1)log("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);


                
    // 使用main方法獲得的參數(shù)args來執(zhí)行process方法,相當(dāng)于:
                
    // startupInstance.process(args);
                
    // 詳情參考類org.apache.catalina.startup.Catalina

                
    if (debug >= 1)log("Calling startup class process() method");
                methodName 
    = "process";
                paramTypes 
    = new Class[1];
                paramTypes[
    0= args.getClass();
                paramValues 
    = new Object[1];
                paramValues[
    0= args;
                method 
    =startupInstance.getClass().getMethod(methodName, paramTypes);
                method.invoke(startupInstance, paramValues);

                }
     catch (Exception e) {
                System.out.println(
    "Exception during startup processing");
                e.printStackTrace(System.out);
                System.exit(
    2);
                     }


        }


        
    /**
         * 返回$CATALINA_HOME變量。如果該變量沒有定義,則將之賦值為用戶的當(dāng)前工作目錄。
         
    */

        
    private static String getCatalinaHome() {
            
    return System.getProperty("catalina.home",System.getProperty("user.dir"));
        }

     
        
    /**
         * 返回$CATALINA_BASE變量。如果該變量沒有定義,則將之賦值為$CATALINA_HOME。
         
    */

        
    private static String getCatalinaBase() {
            
    return System.getProperty("catalina.base", getCatalinaHome());
        }


        
    /**
         * 輸出LOG信息。
         
    */

        
    private static void log(String message) {
            System.out.print(
    "Bootstrap: ");
            System.out.println(message);
        }


        
    /**
         * 輸出由異常引起的LOG信息。
         
    */

        
    private static void log(String message, Throwable exception) {
            log(message);
            exception.printStackTrace(System.out);

        }

    }

    3.2 - org/apache/catalina/startup/ClassLoaderFactory.java
    根據(jù)設(shè)置創(chuàng)建并返回StandardClassLoader的實(shí)例

     


    package org.apache.catalina.startup;

    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.jar.JarEntry;
    import java.util.jar.JarFile;

    import org.apache.catalina.loader.StandardClassLoader;


    /**
    * Utility class for building class loaders for Catalina.The factory
    * method requires the following parameters in order to build a new class
    * loader (with suitable defaults in all cases):
    *    A set of directories containing unpacked classes (and resources)
    *         that should be included in the class loader's
    *         repositories.
    *     
    *    A set of directories containing classes and resources in JAR files.
    *         Each readable JAR file discovered in these directories will be
    *         added to the class loader's repositories.
    *     
    *    ClassLoader instance that should become the parent of the new class loader.
    *     
    *
    @author Craig R. McClanahan
    @version $Revision: 1.8 $ $Date: 2002/02/17 08:26:02 $
    */



    public final class ClassLoaderFactory {
       
    /**
         * Debugging detail level for processing the startup.
        
    */

        
    private static int debug = 0;
        
    /**
         * Return the debugging detail level.
         
    */


        
    public static int getDebug() {
            
    return (debug);
        }

        
    /**
         * 設(shè)置DEBUG級(jí)別
         
    */

        
    public static void setDebug(int newDebug) {
            debug 
    = newDebug;
        }


        
    /**
         * 該類是一個(gè)靜態(tài)類,用來創(chuàng)建和返回ClassLoader對(duì)象(實(shí)際上是StandardClassLoader對(duì)象)
         * 它將根據(jù)設(shè)置和參數(shù)返回apache定置的ClassLoader對(duì)象,以完成自己的類載入
         *
         * 
    @param unpacked 類路徑CLASSPATH的數(shù)組
         * 
    @param packed 含有JAR文件的類路徑
         * 
    @param parent 父ClassLoader對(duì)象。當(dāng)一個(gè)ClassLoader對(duì)象無(wú)法完成類載入時(shí),它將請(qǐng)求父對(duì)象幫助
         *
         * 
    @exception Exception if an error occurs constructing the class loader
         
    */


        
    public static ClassLoader createClassLoader(File unpacked[],File packed[], ClassLoader parent)
            
    throws Exception {
            
    if (debug >= 1)log("Creating new class loader");
            
    // list里將被填入所有需要附加到CLASSPATH上去的文件名
            ArrayList list = new ArrayList();
            
    // Add unpacked directories
            if (unpacked != null{
                
    for (int i = 0; i < unpacked.length; i++)  {
                    File file 
    = unpacked[i];
                    
    if (!file.isDirectory() || !file.exists() || !file.canRead())continue;
                    
    if (debug >= 1)log("  Including directory " + file.getAbsolutePath());
                    URL url 
    = new URL("file"null,file.getCanonicalPath() + File.separator);
                    list.add(url.toString());
                }

            }

            
    // Add packed directory JAR files
            if (packed != null{
                
    for (int i = 0; i < packed.length; i++{
                    File directory 
    = packed[i];
                    
    if (!directory.isDirectory() || !directory.exists() ||!directory.canRead()) continue;
                    String filenames[] 
    = directory.list();
                    
    for (int j = 0; j < filenames.length; j++{
                        String filename 
    = filenames[j].toLowerCase();
                        
    if (!filename.endsWith(".jar"))continue;
                        File file 
    = new File(directory, filenames[j]);
                        
    if (debug >= 1)log("  Including jar file " + file.getAbsolutePath());
                        URL url 
    = new URL("file"null,file.getCanonicalPath());
                        list.add(url.toString());
                    }

                }

            }

            
    // 填好了list
            
    // 創(chuàng)建StandardClassLoader對(duì)象,并返回

            String array[] 
    = (String[]) list.toArray(new String[list.size()]);
            StandardClassLoader classLoader 
    = null;
            
    if (parent == null){
               classLoader 
    = new StandardClassLoader(array); 
            }
    else{
                 classLoader 
    = new StandardClassLoader(array, parent);
            }
               
            classLoader.setDelegate(
    true);
            
    return (classLoader);

        }

        
    /**
         * 輸出日志
         
    */

        
    private static void log(String message) {
            System.out.print(
    "ClassLoaderFactory:  ");
            System.out.println(message);
        }

        
    /**
         * 輸出日志和異常信息
         
    */

        
    private static void log(String message, Throwable exception) {
            log(message);
            exception.printStackTrace(System.out);
        }


    }

    3.3 - org/apache/catalina/loader/StandardClassLoader.java
    類載入器

    3.4 - org/apache/catalina/startup/SecurityClassLoad.java
    該類僅包含一個(gè)靜態(tài)方法,用來為catalinaLoader載入一些類

     


    package org.apache.catalina.startup;


    /**
     * Static class used to preload java classes when using the
     * Java SecurityManager so that the defineClassInPackage
     * RuntimePermission does not trigger an AccessControlException.
     *
     * 
    @author Glenn L. Nielsen
     * 
    @version $Revision: 1.1 $ $Date: 2001/12/30 01:58:20 $
     
    */




    /**
     * 該類只有一個(gè)靜態(tài)方法,其作用僅僅相當(dāng)于一個(gè)函數(shù)
     * 該靜態(tài)方法負(fù)責(zé)載入一些指定的類
     * package org.apache.catalina.core
     * package org.apache.catalina.connector
     * package org.apache.catalina.loader
     * package org.apache.catalina.session
     * package org.apache.catalina.util
     * 這些包都在$CATALINA_HOME/server/catalina.jar文件中
     * (由此看來,該靜態(tài)方法的合法參數(shù)僅為catalinaLoader?)
     
    */



    public final class SecurityClassLoad {

        
    static void securityClassLoad(ClassLoader loader)
            
    throws Exception {

            
    if( System.getSecurityManager() == null )return;

            String basePackage 
    = "org.apache.catalina.";
            loader.loadClass(basePackage 
    + "core.ApplicationContext$PrivilegedGetRequestDispatcher");
            loader.loadClass(basePackage 
    + "core.ApplicationContext$PrivilegedGetResource");
            loader.loadClass(basePackage 
    + "core.ApplicationContext$PrivilegedGetResourcePaths");
            loader.loadClass(basePackage 
    + "core.ApplicationContext$PrivilegedLogMessage");
            loader.loadClass(basePackage 
    + "core.ApplicationContext$PrivilegedLogException");
            loader.loadClass(basePackage 
    + "core.ApplicationContext$PrivilegedLogThrowable");
            loader.loadClass(basePackage 
    + "core.ApplicationDispatcher$PrivilegedForward");
            loader.loadClass(basePackage 
    + "core.ApplicationDispatcher$PrivilegedInclude");
            loader.loadClass(basePackage 
    + "core.ContainerBase$PrivilegedAddChild");
            loader.loadClass(basePackage 
    + "connector.HttpRequestBase$PrivilegedGetSession");
            loader.loadClass(basePackage 
    + "connector.HttpResponseBase$PrivilegedFlushBuffer");
            loader.loadClass(basePackage 
    + "loader.WebappClassLoader$PrivilegedFindResource");
            loader.loadClass(basePackage 
    + "session.StandardSession");
            loader.loadClass(basePackage 
    + "util.CookieTools");
            loader.loadClass(basePackage 
    + "util.URL");
            loader.loadClass(basePackage 
    + "util.Enumerator");
            loader.loadClass(
    "javax.servlet.http.Cookie");

        }

    }


    posted on 2011-12-27 10:25 Eric_jiang 閱讀(622) 評(píng)論(1)  編輯  收藏 所屬分類: Java

    Feedback

    # re: ClassLoader介紹 2011-12-27 10:29 Eric_jiang
    http://www.jobeast.com/puyufanyi  回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 免费一级特黄特色大片| 免费在线看片网站| 亚洲精品无码久久千人斩| 亚洲精品无码av中文字幕| 国产精品美女久久久免费| 成人人观看的免费毛片| 老司机亚洲精品影院无码| 一级一黄在线观看视频免费| 在线观看免费成人| 亚洲色大成网站www尤物| 最近2019免费中文字幕视频三| 久久影视国产亚洲| 国产精品无码亚洲一区二区三区 | 免费看h片的网站| 亚洲精品乱码久久久久久久久久久久 | 国产免费资源高清小视频在线观看| 亚洲美女视频免费| 国产一级片免费看| 夜夜春亚洲嫩草影院| 麻豆安全免费网址入口| 成人au免费视频影院| 亚洲啪AV永久无码精品放毛片| 免费无码又爽又高潮视频| 亚洲AV无码乱码在线观看代蜜桃| 99久久精品国产免费| 亚洲国产精品国自产拍AV| 国产高清对白在线观看免费91 | 亚洲av永久无码嘿嘿嘿| 毛片高清视频在线看免费观看| 亚洲激情校园春色| 最近免费字幕中文大全视频| 亚洲另类图片另类电影| 亚洲一级毛片免费观看| 亚洲 暴爽 AV人人爽日日碰| 一二三四在线播放免费观看中文版视频| 亚洲综合一区二区精品久久| 一个人在线观看视频免费| 爱爱帝国亚洲一区二区三区| 久久久久亚洲av成人无码电影| 久久美女网站免费| 亚洲中文字幕无码av在线|