Tomcatのクラスリーダー


Class loader
参考:http://www.iteye.com/topic/83978
            http://longdick.iteye.com/blog/442213
1,役割:
これはクラスファイルをJVMにロードして、プログラムのために使います。すべてのjava classロードプロセスはこれから始まります。
2,実装:
最上位クラスのクラスリーダーはC++で作られています。jvm運転後、bootstrap classloaderが起動され、メモリに保存され、プログラム起動のためにクラスローディングを行います。
このクラスLoaderはJVMが実行する時にjavaコアのAPIをロードしてjavaプログラムの基本的な需要を満たす。
3,アプリケーションにおけるクラスLoader階層関係
jvmデフォルトクラスLoaderは3つに分けられます。 
     Bootstrap Class Loader:javaベースクラスのロードを担当しています。主に%JRE_です。HOME/lib/カタログの下のrt.jar、reourcess.jar、hasets.jar、classなどです。
     Extension Class Loader:java拡張クラスのロードを担当しています。主に%JRE_です。HOME/lib/extディレクトリのjarとクラス
     App Class Loader:現在のjavaアプリケーションをロードするクラスパスパスのすべてのクラスを担当します。
Class Loaderの呼び出し順序は以下の通りです。
ここの階層は基礎関係ではありません。
一、Class Loader具体的な実現メカニズム:両親依頼モード
    Class Loaderという抽象類にはget PartPart()の方法があり、parent変数があります。
    コードを見ると次の通りです
 protected synchronized Class loadClass(String name, boolean resolve)  
   throws ClassNotFoundException  
   {  
     //      name   class        
    Class c = findLoadedClass(name);  
    if (c == null) {  
    try {  
    if (parent != null) {  
        //  parent  null,   parent loadClass      
         = parent.loadClass(name, false);  
    } else {  
        //parent null,   BootstrapClassLoader      
        c = findBootstrapClass0(name);  
    }  
    } catch (ClassNotFoundException e) {  
        //          ,      findClass                  
        c = findClass(name);  
    }  
}  
  if (resolve) {  
    resolveClass(c);  
 }  
   return c;  
   }  
各クラスのLoaderには一級上のクラスのクラスLoaderがあります。クラスをロードする時、まずPant Class Loaderを呼び出してロードします。もしparentに一級があるなら、一級上のparentを呼び出してロードします。つまり、最終レベルのparentはきっとそうです。
Bootstrap Class Loader。だから、常に優先的にBootstrap Class Loaderを呼んでクラスローディングを行うことを確保しました。そして次のレベルで次のレベルに行きます。
Tomcat Class Loader実現:
  各運行中のスレッドにはメンバーcontext Class Loaderがあり、実行時に他のクラスを動的にロードするために使用されます。システムのデフォルトのcontext Class Loaderはsystem Class Loaderです。だから、javaプログラムは実行時にJVMが持っているクラス、JAVA_を使うことができます。HOME/jre/lib/ext/のクラスとCLASSPATH/のクラスです。Thread.current Thread().set Contact Class Loader(…)を使用できます。現在のスレッドのcontext Class Loaderを変更して、ロードクラスの挙動を変えますが、最終的にはsystem Class Loaderを呼び出します。
今Tomcat起動過程を見ます。
startup.batでcatalina.batを呼び出して、batファイルの中でスタートクラスを見つけます。
set _EXECJAVA=%_RUNJAVA%
set MAINCLASS=org.apache.catalina.startup.Bootstrap
Bootstrap起動クラス中
1,初期化関数:init()
   public void init()
        throws Exception
    {

        // Set Catalina path
        setCatalinaHome();
        setCatalinaBase();

        initClassLoaders();//   ClassLoader

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

        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);

        catalinaDaemon = startupInstance;

    }
では、init Class Loader()関数は以下の通りである。
    private void initClassLoaders() {
        try {
            commonLoader = createClassLoader("common", null);  //common ---system loader
            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 classLoader
            sharedLoader = createClassLoader("shared", commonLoader);//Webapp classloader 
        } catch (Throwable t) {
            log.error("Class loader creation threw exception", t);
            System.exit(1);
        }
    }
見て取れる:
1,現在スレッドに設置されているClass LoaderはCatalina Loaderです。
2,3つのクラスリーダーを初期化しました。commonloader、catalinaloader、sharedleader
    そのうちcatalinaloader、sharedleaderのparent loaderはcommon loaderです。
    それらの役割は以下の通りです。
    --common loader
       このカタログのクラスはTOMCATとすべてのWEB APPに対して見られますが、Webアプリのクラスはこのカタログの下に置くべきではなく、すべての未包装のクラスはCATALINAで構成されています。ホーム/common/classesの下で テイクアウトがあるjarは全部$CATALINAです。HOME/commons/endorsed$CATALINE_ホーム/common/lib下。
デフォルトでは次のようなパッケージが含まれています。
1.naming-common.jar JNDIインターフェースの実現類、Tomcatはこれらの種類を使ってメモリの中でContectを使います。 2.naming-resource.jar JNDIが実現し、Tomcatはそれらを使ってウェブアプリの静的リソースを位置づけます。 3.servlet.jar Servlet、Jsp API 4.xerces.jar XML解像器、特定のWebアプリは自分の/WEB-INF/libでカバーできます。 
    -catalinaloader
デフォルトでは次のいくつかのカバンが含まれています。
                 1.catalina.jar Servlet容器のTomcat実現パッケージ                     2.jakata-regexp-X.Y.jar正規表現で、フィルタを要求する時に使う                     3.servlets-xxxx.jar Servletサポートパッケージ                     4.tomcat-coyote.jar TomcatのCoyote接続実現パッケージ                     5.tomcat-jk.jar Web Serverバインディングパッケージは、TomcatがAacheなどをWeb Serverとしてバインドすることができます。                  6.tomcat-jk.jar機能は同じです。                     7.tomcat-util.jar Tomcat工具類は、いくつかのConnectorに使われるかもしれません。                     8.tomcat-warp.jar Apphe Serverカバンに使用する 
      Tomcatに入れて、すべてのインターフェースのクラスを実現します。これらの種類はWebアプリに対しては全く見られません。すべての未包装の種類は$CATALINAです。HOME/server/classisのjarは全部で$CATALINE_に包んでいます。HOME/server/lib下。
   -sharedleader
デフォルトでは次のいくつかのカバンが含まれています。
1.jasper-compler.jar Jspコンパイラ、JspをServletとコンパイルします。 2.jasper-runtime.jar Jsp(Servletにコンパイルされました)運行サポートパッケージ 3.naming-factory.jarサポートWeb AppはJNDIのパッケージを使用しています。
       すべてのWEB APPにロードして見られる類は、TOMCATには見えません。  $CATALINAHOME/shared/classis、すべてのjarは$CATALINEを包んでいます。HOME/lib下
  
上で呼び出したcreateClass Loader関数を見てください。
 private ClassLoader createClassLoader(String name, ClassLoader parent)
        throws Exception {

	。。。。。 
        ClassLoader classLoader = ClassLoaderFactory.createClassLoader
            (locations, types, parent);

	。。。。。
        return classLoader;

    }
はClass Loader Factory工場クラスを呼び出してクラスLoaderを作成します。
Class Loader FactoryのcreateClass Loader関数では、
        StandardClassLoader classLoader = null;
        if (parent == null)
            classLoader = new StandardClassLoader(array);
        else
            classLoader = new StandardClassLoader(array, parent);
        return (classLoader);
parentは上から伝わってくるcomLoaderです。
standard Class LoaderはURLClassloaderのサブクラスです。 (URLClassloaderはjava.security.SecureClass Loaderのサブクラスで、java.security.SecureClass Loader Class loaderのサブクラスです。  java.security.SecureClass LoaderはClass loaderを拡張しています。彼は関連コードソースと権限定義クラスを使用することもできます。