`
悠悠白鼠
  • 浏览: 14609 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java类加载器(classloader)及类加载路径简介

阅读更多

      昨天,看一个build Standalone中databrusher的一个脚本,发现一个Java类似乎没有在classpath中,好像也可一直运行了。很疑惑,问了对应的开发同学,然后自己好好看了下它的代码,才知道了原理。
命令是:$JAVA_HOME/bin/java $JAVA_OPTS com.alibaba.standalone.AppStartor com.alibaba.intl.standalone.databrusher.Startor "$main_class" "$signal_file" "$recivers"
原理是:Java根据classpath找 到,com.alibaba.standalone.AppStartor这个class,运行这个class,会启动一个classloader来加载 com.alibaba.intl.standalone.databrusher.Startor(在里面会指定到WORLDS-INF目录下加载 类),然后com.alibaba.intl.standalone.databrusher.Startor会启动对应的"$main_class". 
然后,花了挺多时间好好看了一下Java的classloader,了解一下其中的原理和看了下代码。下面也简单总结一下吧。

java虚拟机是由sun.misc.Launcher来初始化的,也就是java(或java.exe)这个程序来做的.虚拟机按以下顺序搜索并装载所有需要的类:
  1,引导类:组成java平台的类,包含rt.jar和i18n.jar等基础jar包中的类.
  2,扩展类:使用java扩展机制的类,都是位于扩展目录($JAVA_HOME/jre/lib/ext)中的.jar档案包.
  3,用户类:开发者定义的类或者没有使用java扩展机制的第三方产品.你必须在命令行中使用-classpath选项或者使用CLASSPATH环境变量来确定这些类的位,或者自己写ClassLoader加载。

Java的class loader的大致情况如下图所示:
http://renyongjie668.blog.163.com/prevPhDownload.do?host=renyongjie668&albumId=197449439&photoId=6568564371
bootstrap classloader -->extension classloader-->system classloader 
虚拟机一启动,会先做一些初始化的动作。一旦初始化动作完成之后,就会产生第一个类加载器,即所谓的Bootstrap ClassLoader,Bootstrap ClassLoader 是由C++ 所撰写而成,这个Bootstrap Loader所做的初始工作中,除了也做一些基本的初始化动作之外,最重要的就是加载定义在sun.misc 命名空间底下的Launcher.java 之中的ExtClassLoader( 因为是inner class ,所以编译之后会变成Launcher$ExtClassLoader.class) ,并设定其Parent 为null,代表其父加载器为Bootstrap Loader 。然后Bootstrap Loader ,再要求加载定义于sun.misc 命名空间底下的Launcher.java 之中的AppClassLoader( 因为是inner class,所以编译之后会变成Launcher$AppClassLoader.class) ,并设定其Parent 为之前产生的ExtClassLoader 实例。
a. Bootstrap ClassLoader/启动类加载器
主要负责java_home/jre/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作.
b. Extension ClassLoader/扩展类加载器
主要负责java_home/jre/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作
c. System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path或$CLASSPATH变量所指的目录下的类与jar包装入工作. (这里需要说明的是,如果$CLASSPATH为空,jdk会默认将被运行的Java类的当前路径作为一个默认的$CLASSPATH,一但设置 了$CLASSPATH变量,则会到$CLASSPATH对应的路径下去寻找相应的类,找不到就会报错。这个结论,我已经经过测试,并且看了下类加载器中 源代码)
d. User Custom ClassLoader/用户自定义类加载类(java.lang.ClassLoader的子类)在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性.

为了有更多的了解,写了个简单的Java程序对前面三种classloader能加载类的路径及其parent类进行了测试。代码如下:

import java.net.URL;
import java.net.URLClassLoader;

 /**
 * @className: IClassLoader
 * @description: 测试三种classloader加载类的路径,及其parent
 * @author: 笑遍世界
 * @createTime: 2010-11-17 下午07:33:40
 */
public class IClassLoader {
    public static void main(String[] args) {
//        测试bootstrap classloader 的类加载路径
        URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for (int i = 0; i < urls.length; i++) {
          System.out.println(urls[i].toExternalForm());
        }
        
//        测试extension classloader 的类加载路径,先打印一个路径,再打印出其parent,然后再打印出类加载路径中的所有jar包
        System.out.println("-------------------------------------");
        System.out.println(System.getProperty("java.ext.dirs"));
        ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
        System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
        System.out.println("extension classloader can use thess jars:");
        URL[] extURLs = ((URLClassLoader)ClassLoader.getSystemClassLoader().getParent()).getURLs();
        for (int i = 0; i < extURLs.length; i++) {
               System.out.println(extURLs[i]);
        }        
        
//      测试system classloader 的类加载路径,其实也就时classpath的路径,并打印出它的parent
        System.out.println("-------------------------------------");
        System.out.println(System.getProperty("java.class.path"));
        System.out.println(ClassLoader.getSystemResource(""));
        ClassLoader systemClassloader=ClassLoader.getSystemClassLoader();
        System.out.println("the parent of system classloader : "+systemClassloader.getParent());
    }
}
本机(linux+jdk1.5)运行结果如下:
file:/usr/ali/java/jre/lib/rt.jar
file:/usr/ali/java/jre/lib/i18n.jar
file:/usr/ali/java/jre/lib/sunrsasign.jar
file:/usr/ali/java/jre/lib/jsse.jar
file:/usr/ali/java/jre/lib/jce.jar
file:/usr/ali/java/jre/lib/charsets.jar
file:/usr/ali/java/jre/classes
-------------------------------------
/usr/ali/java/jre/lib/ext
the parent of extension classloader : null
extension classloader can use thess jars:
file:/usr/ali/java/jre/lib/ext/emma.jar
file:/usr/ali/java/jre/lib/ext/localedata.jar
file:/usr/ali/java/jre/lib/ext/dnsns.jar
file:/usr/ali/java/jre/lib/ext/sunpkcs11.jar
file:/usr/ali/java/jre/lib/ext/sunjce_provider.jar
-------------------------------------
.:/usr/ali/java/lib/dt.jar:/usr/ali/java/lib/tools.jar
file:/home/master/workspace/2010_11/bin/
the parent of system classloader :  sun.misc.Launcher$ExtClassLoader@1a5ab41

//ps:当前路径.即是/home/master/workspace/2010_11/bin/

关于Java的classloader其原理还是需要好好理解才能清楚的,仅通过一天的了解,记录为上面那么多吧。更多详细信息,可以参考如下资料:
http://snandy.iteye.com/blog/307083
http://haofenglemon.iteye.com/blog/426382
http://blog.csdn.net/zdwzzu2006/archive/2008/04/05/2253982.aspx
http://wuquanyin1011.iteye.com/blog/703842
http://hi.baidu.com/yangzhibin_bai/blog/item/78846cce1cb86b0992457ead.html
http://www.blogjava.net/clraychen/archive/2008/02/20/180868.html

分享到:
评论

相关推荐

    indexed-classloader:一个自定义的 JVM 类加载器,它索引类路径元素以获得更快的类资源位置

    索引类加载器一个自定义的 JVM 类加载器,它为类路径元素编制索引,以便更快地定位类/资源。 构建: ./make-jar.sh 要使用,将indexed-classpath.jar添加到类路径并设置-Djava.system.class.loader=org.pantsbuild....

    classloader-servlet:Servlet 在 JEE 环境中查找类加载器路径并调试类加载问题

    Project 提供了两个 servlet ,它们有助于调试 Java Web 应用程序中的类加载问题。 这是一个项目。 JavaEE 兼容版本 servlet 与 Servlet 3.0 规范兼容,只能在 JavaEE 6.0+ 应用程序中使用。 安装 将 Jar 文件放在 ...

    Android开发中类加载器DexClassLoader的简单使用讲解

    标准的Java SDK中有个ClassLoader类,借助此类可以装载需要的class文件,前提是ClassLoader类初始化必须制定class文件的路径。 import关键字引用的类文件和ClassLoader动态加载类的区别: import引用类的两个特点: ...

    day020-继承加强和设计模式代码和笔记.rar

    系统类 (应用类)加载器(Application classLoader): 系统类加载器是由 Sun 的 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的, 它负责将 用户类路径(java -classpath或-Djava.class....

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    chapter15 反射与类加载器 499 15.1 运用反射 500 15.1.1 class与.class文档 500 15.1.2 使用class.forname() 502 15.1.3 从class获得信息 503 15.1.4 从class建立对象 506 15.1.5 操作对象方法与成员 ...

    小白的20天Java学习打卡day2

    JVM启动之后会启动类加载器ClassLoader ClassLoader会在硬盘上的某个位置搜索HelloWorld.class字节码文件 找到该文件则执行 找不到该文件则报错​ ​ 疑问:CassLoader是在哪个位置上搜索HelloWorld.class字节码...

    Java 2平台安全技术-结构,API设计和实现

    3.9.1 类加载器的层次 44 3.9.2 java.lang.ClassLoader和授权 46 3.9.3 java.security.SecureClassLoader 49 3.9.4 java.net.URLClassLoader 49 3.9.5 类的路径 50 3.10 java.lang.SecurityManager 51 3.10.1 使用...

    JAVA 2平台安全技术-结构,API设计和实现

    3.9.1 类加载器的层次 44 3.9.2 java.lang.ClassLoader和授权 46 3.9.3 java.security.SecureClassLoader 49 3.9.4 java.net.URLClassLoader 49 3.9.5 类的路径 50 3.10 java.lang.SecurityManager 51 3.10.1 使用...

    ironjacamar-spec-api-1.1.2.Final.zip

    path-classloader.zip,在Java7(JSR-203)文件系统路径上工作的类加载器。在Java7(JSR-203)文件系统路径上工作的类加载器。

    Java编程经验

    这3个加载器分别对应着编译器去寻找类文件的优先级别和不同的路径:BootClassLoader对应jre/classes路径,是编译器最优先寻找class的地方 ExtClassLoader对应jre/lib/ext路径,是编译器次优先寻找class的地方 ...

    java 面试题 总结

    java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类 3、int 和 Integer 有什么区别 Java 提供两种不同的类型:引用类型和原始类型(或内置...

    JAVA面试题最全集

    37.classloader中,JDK的API、Classpath中的同web-inf中的class加载方式有什么区别? 38.列举三种以上垃圾回收算法,并比较其优缺点? 39.编写代码实现一个线程池 40.描述一下JVM加载class文件的原理机制? 41....

    java-class-enumerator:用于动态发现Java类的简单代码。 见http

    更糟糕的是,类加载器将按需加载类,并且部分类路径可能位于网络连接的另一端。 可以解决更严格的问题。 例如,JAR文件中的所有类,或JAR文件在特定程序包中定义的所有类。 无论如何,这是更常见的情况。 不幸的是...

    jre-8u202-windows-i586.exe

    JRE中由ClassLoader负责查找和加载程序引用到的类库,基础类库ClassLoader会到rt.jar中自动加载,其它的类库,ClassLoader在环境变量CLASSPATH指定的路径中搜索,按照先来先到的原则,放在CLASSPATH前面的类库先被...

    jre8u202i586.zip

    JRE中由ClassLoader负责查找和加载程序引用到的类库,基础类库ClassLoader会到rt.jar中自动加载,其它的类库,ClassLoader在环境变量CLASSPATH指定的路径中搜索,按照先来先到的原则,放在CLASSPATH前面的类库先被...

    hermgen:基于Hazelcast的分布式ClassLoader和PermGen

    HermGen的分布式类加载器首先在类路径中搜索类。 然后,如果无法在类路径中找到所请求的类,HermGen会向群集中的其他成员发送工作程序,以获取所请求类的字节码。 这些工作程序在其他成员上运行,并在其他成员上...

    超级有影响力霸气的Java面试题大全文档

     java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类 6、int 和 Integer 有什么区别  Java 提供两种不同的类型:引用类型和原始类型(或...

    ClassLoaderJava

    类加载器Java 程序是为 JVM Internals 2015 格但斯克大学编写的 ##关于程序 我们必须编写在应用程序的生命周期内替换类定义的程序。 这种替换应该在没有用户参与的情况下进行。 应用程序,实际上覆盖了 ClassLoader...

    eclipse-project-loader:ClassLoder 用于Eclipse项目中资源文件的高效引用

    Eclipse 项目加载器一个用于随时加载 Eclipse 项目资源而无需重新加载项目的 ClassLoader。 它可以通过在Eclipse的调试配置中指定-Djava.system.class.loader=...

    基于模板的代码生成器LKGenerator1.1.0_x64

    实现思路:加载实体类的class文件到classLoader中,读取实体类的属性和注解,将类名、属性字段名、注解三者与模版进行结合生成最终的代码。 1.配置 (1)配置模版路径,这个配置可以配置用于生成代码的velocity模版...

Global site tag (gtag.js) - Google Analytics