`
penchy
  • 浏览: 57663 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java类加载器介绍

    博客分类:
  • JAVA
阅读更多

Java类加载器介绍 

类加载器负责把类加载到Java虚拟机(JVM)中。指定类的名称,类加载器就会定位这个类的定义,每一个Java类必须由类加载器加载。

当启动JVM的时候,可以使用三个类加载器:引导(bootstrap)类加载器、扩展(extensions)类加载器、应用程序(application)类加载器。

1.引导类加载器仅仅负责加载核心的Java库,比如位于<JAVA_HOME>/jre/lib 目录下的vm.jar,core.jar。这个类加载器,是JVM核心部分,是用native代码写成的。

2. 扩展类加载器负责加载扩展路径下的代码,一般位于<JAVA_HOME>/jre/lib/ext  或者通过java.ext.dirs 这个系统属性指定的路径下的代码。这个类加载器是由sun.misc.Launcher$ExtClassLoader 实现的。

3.应用程序类加载器负责加载java.class.path(映射系统参数 CLASSPATH的值) 路径下面的代码,这个类加载器是由 sun.misc.Launcher$AppClassLoader 实现的。

当处理类加载器时,父委托模式是一个需要理解的关键概念。它规定:类加载器在加载自己的类之前,可以委托先加载父类。父类加载器可以是客户化的类加载器或者引导类加载器。但是有一点很重要,类加载器只能委托自己的父类加载器,而不能是子类加载器(只能向上不能向下)。

扩展类加载器是应用程序类加载器的父亲。类加载器的层次图见图12-1 。

图12-1 类加载器层次图


如果应用程序类加载器需要加载一个类,它首先委托扩展类加载器,扩展类加载器再委托引导类加载器。如果父类加载器不能加载类,子类加载器就回在自己的库中查找这个类。基于这个特性,类加载器只负责它的祖先无法加载的类。

如 果类加载器加载一个类,这个类不是在类加载器树上的叶子节点上,就会出现一些有趣的问题。比如例12-1,一个名为WhichClassLoader1 的类加载了一个名为WhichClassLoader2类,WhichClassLoader2又调用了名为WhichClassLoader3的类。

例12-1 WhichClassLoader1 和 WhichClassLoader2 源代码

public class WhichClassLoader1 {

public static void main(String[] args) throws javax.naming.NamingException

{

// Get classpath values

String bootClassPath = System.getProperty("sun.boot.class.path");

String extClassPath = System.getProperty("java.ext.dirs");

String appClassPath = System.getProperty("java.class.path");

// Print them out

System.out.println("Bootstrap classpath =" + bootClassPath + "\n");

System.out.println("Extensions classpath =" + extClassPath + "\n");

System.out.println("Application classpath=" + appClassPath + "\n");

// Load classes

Object bj = new Object();

WhichClassLoader1 wcl1 = new WhichClassLoader1();

WhichClassLoader2 wcl2 = new WhichClassLoader2();

// Who loaded what?

System.out.println("Object was loaded by "

+ obj.getClass().getClassLoader());

System.out.println("WCL1 was loaded by "

+ wcl1.getClass().getClassLoader());

System.out.println("WCL2 was loaded by "

+ wcl2.getClass().getClassLoader());

wcl2.getTheClass();

}

}


========================================================

 

public class WhichClassLoader2 {

// This method is invoked from WhichClassLoader1

public void getTheClass() {

WhichClassLoader3 wcl3 = new WhichClassLoader3();

System.out.println("WCL3 was loaded by "

+ wcl3.getClass().getClassLoader());

}

}
 

 

 

如 果所有的WhichClassLoaderX 类都放在应用程序的类路径下,三个类就会被应用程序类加载器加载,这个例子就会运行正常。现在假定把WhichClassLoader2 类文件打包成JAR文件放在<JAVA_HOME>/jre/lib/ext 目录下,运行WhichClassLoader1,就会看到例12-2的输出:

例12-2 NoClassDefFoundError  异常跟踪

Bootstrap classpath

=C:\WebSphere\AppServer\java\jre\lib\vm.jar;C:\WebSphere\AppServer\java\jre\lib

\core.jar;C:\WebSphere\AppServer\java\jre\lib\charsets.jar;C:\WebSphere\AppServ

er\java\jre\lib\graphics.jar;C:\WebSphere\AppServer\java\jre\lib\security.jar;C

:\WebSphere\AppServer\java\jre\lib\ibmpkcs.jar;C:\WebSphere\AppServer\java\jre\

lib\ibmorb.jar;C:\WebSphere\AppServer\java\jre\lib\ibmcfw.jar;C:\WebSphere\AppS

erver\java\jre\lib\ibmorbapi.jar;C:\WebSphere\AppServer\java\jre\lib\ibmjcefw.j

ar;C:\WebSphere\AppServer\java\jre\lib\ibmjgssprovider.jar;C:\WebSphere\AppServ

er\java\jre\lib\ibmjsseprovider2.jar;C:\WebSphere\AppServer\java\jre\lib\ibmjaa

slm.jar;C:\WebSphere\AppServer\java\jre\lib\ibmjaasactivelm.jar;C:\WebSphere\Ap

pServer\java\jre\lib\ibmcertpathprovider.jar;C:\WebSphere\AppServer\java\jre\li

b\server.jar;C:\WebSphere\AppServer\java\jre\lib\xml.jar

Extensions classpath =C:\WebSphere\AppServer\java\jre\lib\ext

Application classpath=.

Exception in thread "main" java.lang.NoClassDefFoundError: WhichClassLoader3

at java.lang.J9VMInternals.verifyImpl(Native Method)

at java.lang.J9VMInternals.verify(J9VMInternals.java:59)

at java.lang.J9VMInternals.initialize(J9VMInternals.java:120)

at WhichClassLoader1.main(WhichClassLoader1.java:17)

正 如所看到的,由于WhichClassLoader3 在应用程序类路径下,程序失败,收到一个NoClassDefFoundError 的异常,这看起来有些奇怪。问题在于:它现在在一个错误的类路径下面。当WhichClassLoader2被扩展类加载器加载的时候,发生了什么呢?实 际上,应用程序类加载器委托扩展类加载器加载WhichClassLoader2,扩展类加载器又委托引导类加载器。由于引导类加载器找不到这个类,类加 载的控制就会返回给扩展类加载器。扩展类加载器在自己的路径下找到了这个类将它加载。现在,当一个类已经被类加载器加载后,这个类需要的任何其他的新类都 必须用同一个类加载器加载他们(或者遵循父委托模式,由父类加载器加载)。所以当WhichClassLoader2 需要访问WhichClassLoader3 的时候,扩展类加载器就会获得这个请求去加载WhichClassLoader3,扩展类加载器先委托引导类加载器,但是引导类加载器找不到这个类,于是 扩展类加载器便试图装入自身但是也找不到这个类,原因是WhichClassLoader3不在扩展类路径而是在应用程序类路径。由于扩展类加载器无法委 托应用程序类加载器,所以就会出现NoClassDefFoundError 的异常。

 注意: 开发者通常会使用如下语法通过类加载器机制加载属性文件:

Properties p = new Properties();

p.load(MyClass.class.getClassLoader().getResourceAsStream("myApp.properties"

));

这个意思是:如果MyClass 由扩展类加载器加载,而 myApp.properties 文件只能应用程序类加载器看到,则装入属性文件就会失败。

  • 大小: 12.9 KB
分享到:
评论

相关推荐

    java类加载器

    java类加载器介绍和解释,有例子,图片。

    自定义Java类加载器

    看完一个Java加载原理教程后,写了这个自己的类加载器,作个笔记,以便以且使用

    java类加载器实例

    类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...

    java 类加载器 加密

    java 类加密 使用类加载器解密加载类 反射执行main

    java类加载器学习三、类加载器的委托模式

    java类加载器学习三、类加载器的委托模式

    Java类加载器.pdf

    Java类加载器.pdf

    java 类加载器 class loader

    java 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loader

    java类装载器学习一、类加载器的基本概念

    类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念

    深入探讨 Java 类加载器.wps

    深入探讨 Java 类加载器.wps深入探讨 Java 类加载器.wps深入探讨 Java 类加载器.wps

    自定义Java类加载器demo

    自定义Java类加载器demo,自定义了一个classLoader,重写了loadClass 和findClass,注意 loadClass打破了双亲委派机制,所有的类都要在自定义的class文件中找到,而findClass遵循了双亲委派机制

    Java类加载器原理

    自己根据一些文章总结的,不知道有没有漏洞,希望大家知道,谢谢

    java类加载器和反射学习要点ppt

    本学习讲义是关于java类加载和反射机制需要注意的要点学习,内容详细

    深入探讨 Java 类加载器

    类加载器(class ...本文首先详细介绍了 Java 类加载器的基本概念,包括代理模式、加载类的具体过程和线程上下文类加载器等,接着介绍如何开发自己的类加载器,最后介绍了类加载器在 Web 容器和 OSGi™ 中的应用。

    类加载器(java)

    当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构,理解类加载器:J2EE 环境下的 log4j.files

    掌握Java类加载器

    类加载器是Java最强大的特征之一。但是开发者常常忘记类加载组件。类加载器是在运行时负责寻找和加载类文件的类。Java允许使用不同的类加载器,甚至自定义的类加载器。类加载器从源文件(通常是.class 或 .jar文件)...

    ModRunJava类加载器可以直接从Maven存储库加载并运行类

    Java类加载器可以直接从Maven存储库加载并运行类,能在运行时解决依赖关系

    java类加载器学习二、自定义类加载器

    java类加载器学习二、自定义类加载器

    java类加载机制.xmind

    该文件是JVM中关于类加载机制的知识整理的思维导图,包括类加载机制概述、类加载的生命周期、加载时机、加载过程、类加载、类的初始化和实例化等几个大方面进行了讲解,其中类加载中还对JVM三种预定义类加载器进行了...

    java应用程序类加载器,ClassLoader for java Application

    java应用程序类加载器(ClassLoader for java Application),类似exe4j, 方便启动java程序, 配置灵活,支持多平台选择性配置

Global site tag (gtag.js) - Google Analytics