2013/12/16

java tomat classLoader

★★Javaはクラスが最初に参照された際,その時点で使用しているクラスローダーを使用して,クラスパスからクラスファイルをロードし,その参照をクラスローダー自身に保持します.

クラスローダーの細かい仕組みを触る
    ・JVM起動の際,java.*などの標準のクラス群をロードするクラスローダー
    ・JVMが起動後,mainメソッドを保持するアプリケーションプログラムをロードするクラスローダー
    ・その他,自分で勝手に作成したクラスローダー
   
   
最初のやつは「ブートストラップクラスローダー」で,次のが「システムクラスローダー」で,最後のヤツが単なるアプリケーションのクラスローダーです.

クラスローダーには親子関係があり,ブートストラップクラスローダーが一番の親,その子がシステムクラスローダー,我々が独自に作成するクラスローダーは,システムクラスローダーの子となります.もちろん,我々が独自に作成したクラスローダー間にも,親子関係を持たせることもできます.

ブートストラップクラスローダーは,JAVA_HOME/lib/*.jarなどに対してのクラスパスを保持しています.
システムクラスローダーは,javaコマンドの引数(または環境変数CLASSPATH)によって指定されたクラスパスを保持しています.

クラスがロードされる際,親から末端の子クラスローダーへ,順番にロード処理が行われます.
親クラスローダーが,既にクラスの参照を保持している場合,それが使用され,クラスファイルはロードされません.

何が言いたかったのかといいますと,JVM起動中にロード/アンロードしたいクラスは,アプリケーション起動時のクラスパスに含めてはならない,ということです.
アプリケーション起動時のクラスパスに含めるということは,システムクラスローダーがそれらをロードし,そして変更できなくなってしまうからです(JVM起動中にシステムクラスローダーを破棄することはできません).

★★


l  Tomcatcontainer中需要一个自定义的loader,不能简单的直接使用系统的loader,因为所要运行的servlet是不可信任的。假如像使用之前章节一样使用系统中的loader,则该loader载入的servlet和其他类就能访问当前jvm实例中CLASSPATH环境变量下所有的类了,这非常不安全servlet应该仅仅被允WEB-INF/classes及其子目,和WEB-INF/lib下部署lib。因此,servlet容器需要一个自定loader。每一个web对应context容器)都有一个自定loader。在catalina中,loader件要实现org.apache.catalina.Loader接口。
l  使用自定loader的另一个原因是,可以支持class的自tomcat中的loader实现使用了另一个线程来检查servlet和相关时间戳,若是化,重新入。了支持class的重loader实现org.apache.catalina.loader.Reloader接口
l  tomcat 中使用自定义类载入器的原因如下: (1)指定明确的类载入规则 (2)缓存已经载入的类 (3)预载入某个类,更方便使用。
l  jvm使用三种loader:引导类载入器(bootstrap class loader),类载入器(extension class loader)和系统类载入器(system class loader)。三种有着父子承关系(引导类载入位于最高)。 导类载入器(bootstrap class loader)用于引jvm。当使用java命令,引导类载入器开始工作。引导类载入是使用本地方法实现的,因它要负责载入启jvm。此外,它负责载java核心,例如java.iojava.lang包下的,它的搜索路径包括rt.jari18n.jar等包,具体找哪些包依jvm和操作系的版本。
类载入器(extension class loader负责载展目下的有利与程序开,因程序只需要将jar包拷展目中,类载入器会从jar包中找需要的展目jvm的具体实现sunjvm实现展目/jdk/jre/lib/ext 统类载入器(system class loader是默类载入器,从CLASSPATH中搜索需要的 那么,jvm到底使用哪个loader呢?了尽可能的安全,jvm问题上使用代理模型。每次需要入一个新类时,首先使用系统类载入器。但是,该类并不会被立刻入。相反,系统类载入器将个任代理给扩类载入器行,而类载入器又将代理导类载入器行。因此,引导类载入器实际上是先的。当引导类载入器无法类时类载入器尝试载,若类载入器也入失统类载入器尝试载入,若是失,抛出java.lang.ClassNotFoundException异常。