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

Bootstrap、Extension、Application Class Loader

 
阅读更多

        Bootstrap Class Loader ,Extension Class Loader ,Application Class Loader三种Class Loader是JVM 系统已经事先实现。
        Bootstrap Class Loader 采用的是C或其他相应语言编写(根据JRE 操作系统版本不同而不同),其他两种Class Loader 均采用Java 语言编写,他们的实现为ExtClassLoader 与AppClassLoader 两个内部静态类,位于sun.misc.Launcher内,而Launcher则位于rt.jar中。
        以下网址可以下载JDK 的源码实现:
        http://download.java.net/openjdk/jdk6/
        通过源码可以是我们更进一步了解Class Loader 的内部实现及流程。

 

        Bootstrap Class Loader
        Bootstrap Class Loader 的实现位于${openjdk}\hotspot\src\share\vm\classfile 目录下的 classLoader.cpp 与classLoader.hpp,打开源代码可以发现Bootstrap Class Loader是采用C++ 编写的,这就是上一节代码中为什么得不到Bootstrap Class Loader 对象的原因。

        该ClassLoader 可以做到根据类文件名来加载类,这其实就和java.lang.ClassLoader 的loadClass 功能非常相近了。

ClassFileStream* ClassPathDirEntry::open_stream(const char* name)  {
  ...
  jio_snprintf(path, sizeof(path), "%s%s%s", _dir, 
               os::file_separator(), name)
  ...
}

 

        可以看到path=_dir + 文件分隔符 + name,得到path 后,就是读取文件并存放到byte[] 的过程了。

要想path 直接可用,得有两个前提:

        (1) _dir事先已经配置好;
        (2)name 也应该先经过了处理;
        例如:
        java.lang.String,会先被转换成java/lang/String.class;
        又假如:
        _dir 为/usr/local/java/src;
        name 为com/test/HelloWorld.class;
        path 最终即为/usr/local/java/src/com/test/HelloWorld.class;


        加载类文件过程:

instanceKlassHandle ClassLoader::load_classfile(symbolHandle h_name, TRAPS) {
  ResourceMark rm(THREAD);
  EventMark m("loading class " INTPTR_FORMAT, (address)h_name());
  ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);

  stringStream st;
  // st.print() uses too much stack space while handling a StackOverflowError
  // st.print("%s.class", h_name->as_utf8());
  st.print_raw(h_name->as_utf8());
  st.print_raw(".class");
  char* name = st.as_string();

  // Lookup stream for parsing .class file
  ClassFileStream* stream = NULL;
  int classpath_index = 0;
  {
    PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
                               ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
                               PerfClassTraceTime::CLASS_LOAD);
    ClassPathEntry* e = _first_entry;
    while (e != NULL) {
      stream = e->open_stream(name);
      if (stream != NULL) {
        break;
      }
      e = e->next();
      ++classpath_index;
    }
  }

  instanceKlassHandle h(THREAD, klassOop(NULL));
  if (stream != NULL) {

    // class file found, parse it
    ClassFileParser parser(stream);
    Handle class_loader;
    Handle protection_domain;
    symbolHandle parsed_name;
    instanceKlassHandle result = parser.parseClassFile(h_name,
                                                       class_loader,
                                                       protection_domain,
                                                       parsed_name,
                                                       false,
                                                       CHECK_(h));

    // add to package table
    if (add_package(name, classpath_index, THREAD)) {
      h = result;
    }
  }

  return h;
}

 

        初始化过程:

void ClassLoader::initialize() {
  ...
  // lookup zip library entry points
  load_zip_library();
  // initialize search path
  setup_bootstrap_search_path();
  ...
}

 

        其中load_zip_library() 即加载zip 类库,从而便于处理jar (可以认为jar 是一种特殊的zip 压缩);而setup_bootstrap_search_path() 即为初始化BootstrapClassLoader 的查找路径,其实就是在初始化上文中每个ClassPathEntry 的_dir。

        打开${openjdk}\hotspot\src\share\vm\runtime\os.cpp 文件,找到set_boot_path()方法,会发现Bootstrap Class Loader 已经将所要加载的类库jar 文件固化至代码中了,这些就是JVM 启动时必须要加载的文件。

bool os::set_boot_path(char fileSep, char pathSep) {
    const char* home = Arguments::get_java_home();
    int home_len = (int)strlen(home);

    static const char* meta_index_dir_format = "%/lib/";
    static const char* meta_index_format = "%/lib/meta-index";
    char* meta_index = format_boot_path(meta_index_format, home, home_len, fileSep, pathSep);
    if (meta_index == NULL) return false;
    char* meta_index_dir = format_boot_path(meta_index_dir_format, home, home_len, fileSep, pathSep);
    if (meta_index_dir == NULL) return false;
    Arguments::set_meta_index_path(meta_index, meta_index_dir);

    // Any modification to the JAR-file list, for the boot classpath must be
    // aligned with install/install/make/common/Pack.gmk. Note: boot class
    // path class JARs, are stripped for StackMapTable to reduce download size.
    static const char classpath_format[] =
        "%/lib/resources.jar:"
        "%/lib/rt.jar:"
        "%/lib/sunrsasign.jar:"
        "%/lib/jsse.jar:"
        "%/lib/jce.jar:"
        "%/lib/charsets.jar:"

        // ## TEMPORARY hack to keep the legacy launcher working when
        // ## only the boot module is installed (cf. j.l.ClassLoader)
        "%/lib/modules/jdk.boot.jar:"

        "%/classes";
    char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep);
    if (sysclasspath == NULL) return false;
    Arguments::set_sysclasspath(sysclasspath);

    return true;
}

 

        本人对C++ 不甚了解,所以无法就代码及流程做更进一步的讲解,希望大家谅解,也欢迎大家补充。

 

 

        AppClassLoader 与ExtClassLoader

        打开sun.misc.Launcher 的源代码,源代码位置在${openjdk}\jdk\src\share\classes\sun\misc\Launcher.java ,ExtClassLoader 与AppClassLoader 是Launcher 类的内部类,代码如下:

/*
* The class loader used for loading installed extensions.
*/
static class ExtClassLoader extends URLClassLoader {}

/**
* The class loader used for loading from java.class.path.
* runs in a restricted security context.
*/
static class AppClassLoader extends URLClassLoader {}

 

        从继承关系可以向上一直追溯直至java.lang.ClassLoader 实现类,两者的继承关系如下:

java.lang.Object
	--- java.lang.ClassLoader
		--- java.security.SecureClassLoader
			---  java.net.URLClassLoader
				--- sun.misc.Launcher$ExtClassLoader


java.lang.Object
	--- java.lang.ClassLoader
		--- java.security.SecureClassLoader
			---  java.net.URLClassLoader
				--- sun.misc.Launcher$AppClassLoader

 

        从下图可以更直观的观察出他们的继承关系(引用自网络):



 

        AppClassLoader 与ExtClassLoader 基本都是调用父类的方法,只是在其中加入了一些相应的业务逻辑,所以这里就不分析他们了,在ClassLoader这节中会更详细的分析。

  • 大小: 50.4 KB
2
6
分享到:
评论

相关推荐

    java 类加载器 class loader

    创建自定义类加载器通常需要继承`java.lang.ClassLoader`,重写`findClass()`或`loadClass()`方法,从而控制类的查找和加载过程。这使得开发者能够在运行时根据需要加载特定的类,比如从网络、数据库或其他非传统...

    java自定义类加载classloader文档,包括代码

    Extension Class Loader的父加载器为Bootstrap Class Loader。 3. **Application Class Loader(应用程序类加载器)**:也称为系统类加载器,由`sun.misc.Launcher$AppClassLoader`实现。它负责加载用户类路径...

    class loader

    - **Extension ClassLoader**:位于Bootstrap ClassLoader之上,负责加载扩展目录(如`lib/ext`)下的jar包。 - **Application ClassLoader**:这是默认的应用程序类加载器,负责加载应用程序classpath下的类。 ...

    WebSphere Application Server V7 理解类装入器 中文翻译版

    - **扩展类装入器(Extension Class Loader)**:由`sun.misc.Launcher$ExtClassLoader`实现,用于加载扩展目录(`JAVA_HOME/jre/lib/ext`或由`java.ext.dirs`系统属性指定的位置)中的jar文件。 - **应用程序类装入器...

    java类加载器

    3. **应用程序类加载器(Application Class Loader)**:也称为系统类加载器,它根据`java.class.path`系统属性加载应用的类。这是开发者最常打交道的类加载器。 自定义类加载器允许开发者实现特定的加载逻辑,例如从...

    Java类加载机制

    3. **应用类加载器(Application Class Loader)**:也称为系统类加载器,它是默认的类加载器,负责加载当前应用程序的类路径(classpath)中定义的类。 4. **自定义类加载器(Custom Class Loader)**:开发者可以...

    Java深度历险CH02

    3. **应用类别加载器**(Application Class Loader):最常见的一种类别加载器,用于加载用户应用程序的类,通常是通过`ClassLoader#getSystemClassLoader()`获取。 #### 自定义类别加载器 除了这些标准的类别加载...

    java虚拟机

    类加载器包括bootstrap class loader(引导类加载器)、extension class loader(扩展类加载器)和application class loader(应用程序类加载器),以及用户自定义的类加载器。 3. **内存区域**:JVM内存主要分为堆...

    java中四个核心思想

    - **启动类装载器(Bootstrap Class Loader)**:这是系统级的类装载器,用于装载Java的核心类库,如`java.lang.*`等,它是所有其他类装载器的父类装载器。 - **扩展类装载器(Extension Class Loader)**:用于装载扩展...

    JVM演讲PPT分享

    类加载器分为引导类加载器(Bootstrap Class Loader)、扩展类加载器(Extension Class Loader)和系统类加载器(System Class Loader)。 运行时数据区(Runtime Data Areas) 运行时数据区是JVM内存模型的核心,...

    Java 类加载机制 ClassLoader Class.forName.pdf

    1. **Bootstrap ClassLoader** 的搜索路径由`System.getProperty("sun.boot.class.path")`指定,通常包含了JVM的核心类库。 2. **Extension ClassLoader** 的搜索路径由`System.getProperty("java.ext.dirs")`指定,...

    Java虚拟机(JVM)面试题

    类加载器主要有三个:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。Bootstrap ClassLoader是最基础的类加载器,Extension ClassLoader是扩展类加载器,Application ClassLoader是应用...

    JBoss管理与开发

    - **Application Class Loader**:通常是`sun.misc.Launcher$AppClassLoader`的实例,负责加载用户应用程序的类。 此外,应用程序还可以自定义类装载器来满足特定需求。 ###### 2.2.2 JBoss的类装载器架构改进 在...

    Java轻松掌握

    - **类加载器**:负责加载类到JVM,分为bootstrap class loader、extension class loader和application class loader。 以上就是“Java轻松掌握”涵盖的一些主要知识点,通过深入学习和实践,你将能够熟练掌握Java...

    java虚拟机的详细原理

    - **引导类加载器**(Bootstrap Class Loader):负责加载核心类库,如`java.lang.*`等。 - **扩展类加载器**(Extension Class Loader):加载扩展目录中的类库。 - **应用程序类加载器**(Application Class ...

    jvm开发实战项目案例分析

    JVM有多个类加载器,如bootstrap loader、extension loader、application loader等,它们共同构成了类加载的双亲委托模型。理解这个模型有助于解决类冲突和安全问题。 还有,JVM的编译优化(JIT,Just-In-Time编译...

Global site tag (gtag.js) - Google Analytics