浅析Context Class Loader

转载 2009年11月19日 11:33:00

 转载自 薛笛的专栏 http://blog.csdn.net/kabini/archive/2008/09/24/2975263.aspx

 

浅析Context Class Loader

 

1 前言

对于一般的Java应用而言,类装载器是透明的,我们在做普通的Java桌面应用程序和Web程序的时候也很少会与ClassLoader打交道。但是当我们深入地研究一些WebServer(如Tomcat)的时候,发现里面用到了很复杂的自定义类装载器体系结构,想要了解其工作过程首先就要理解它是如何载如类的。此外,当我们明明在ClassPath下指定了正确的jar包,却莫名其妙地受到ClassNotFound错误,或者我们放到ClassPath下的类没有被正确载入的时候,就需要和ClassLoader打交道了。这里我不打算讨论基本的JVM的类装载器体系结构和原理,因为这些东西已经在《Java深度历险》或者《Inside Of  JVM》里讲的很透彻了。本文旨在分享一下我对于各种文档上都很少提及的Context Class Loader的一些理解。虽然不是点到为止,但是肯定多有疏漏之处,希望对此有研究的朋友留言帮我补充,现行谢过。

2准备

通常情况下,类装载器共有4种,即启动类装载器、EXT类装载器、App类装载器和自定义类装载器。他们之间的阶层情况如下图左面所示,他们都有着不同的载入规则,并且通过向上代理的方式来进行。而本文所提到的Context Class Loader并不是一种新的装载器类型,而是一种抽象的说法,它的具体表现形式为:调用Thread.getCurrentThread().getContextClassLoader()所返回的那个ClassLoader。它和JVM缺省的类装载器以及自定义类装载之间是什么关系呢?下面通过一个实验来看一下。

 

3 实战演练

(1)步骤一

上图进行了这样一个实验:首先一个名为Class(1)的类中启动MainThread(其实就是这个类里面有main函数的意思啦),注意这个类的名字后面标出了其所在的路径(即ClassPath),然后在里面进行测试,发现目前它的装载器和当前线程(MainThread)的ContextClassLoader都是AppClassLoader。然后Class(1)启动了一个新线程Class(2)。这里的Class(2)是一个Thread的子类,执行Class(2)代码的线程我称之为Thread-0。

(2)步骤二

上图可以看到Class(2)的装载器和ContextClassLoader同样都是AppClassLoader。随后我在Class(2)中创建了一个新的URLCLassLoader,并用这个ClassLoader来载入另一个和Class(1)不在同一个ClassPath下的类Class(3)。此时我们就可以看到变化:即载入Class(3)的装载器是URLClassLoader,而ContextClassLoader还仍然是AppClassLoader。

(2)步骤三

最后我们在Class(3)中启动了一个线程类Class(4),发现Class(4)也是由URLClassLoader载入的,而此时ContextClassLoader仍然是AppClassLoader。

    在整个过程中,装载类的ClassLoader发生了变化,由于线程类Class(4)是由Class(3)启动的,所以装载它的类装载器就变成了URLClassLoader。与此同时,所有线程的ContextClassLoader都继承了生成该线程的ContextClassLoader--AppClassLoader。

 

如果我们在第二步的结尾执行了绿色框中的代码:setContextClassLoader(),则结果就会变成下面这个样子:

 

 

 

 

我们可以清楚地看到,由于Thread-0将其ContextClassLoader设置成了URLClassLoader,而Thread-1是在Thread-0里面生成的,所以就继承了其ContextClassLoader,变成了URLClassLoader。

浅析Context Class Loader

 浅析Context Class Loader 1 前言对于一般的Java应用而言,类装载器是透明的,我们在做普通的Java桌面应用程序和Web程序的时候也很少会与ClassLoader打交道。但是当...
  • kabini
  • kabini
  • 2008年09月24日 22:59
  • 13119

javax.naming.NamingException: No naming context bound to this class loader

1、错误描述警告: Failed to retrieve JNDI naming context for container [StandardEngine[Catalina].StandardHos...
  • you23hai45
  • you23hai45
  • 2015年11月21日 23:59
  • 17957

开发问题日记

1.interface org.springframework.aop.SpringProxy is not visible from class loader 解决方法:引入spring  aop...
  • gongli109
  • gongli109
  • 2015年05月28日 10:26
  • 8947

Tomcat 中自定义Context Loader

一. 问题  在开发若干个类似项目的时候,通常这些 Webapp 的lib 都是一样的,可以将其放到一个公共的目录,这样部署的应用就会小很多。 比如 一个带有Spirng + JPA 的通常Lib 都...
  • maoxiang
  • maoxiang
  • 2010年08月10日 10:19
  • 3506

tomcat启动报javax.naming.NamingException: No naming context bound to this class loader

tomcat启动报如下错误 javax.naming.NamingException: No naming context bound to this class loader     at ...
  • guo315648865
  • guo315648865
  • 2016年04月01日 10:09
  • 7774

开发问题整理

1、java - Tomcat Error: WARNING: Failed to retrieve JNDI naming context for container javax.naming.Na...
  • m0_37366775
  • m0_37366775
  • 2017年06月24日 13:04
  • 125

GWT + Spring : javax.naming.NameNotFoundException: Name userDao is not bound in this Context

1 )开发一个CRM项目, SmartGwt + Hibernate + Spring JDK 1.6GWT1.7.1SmartGwt 1.3Hibernate 3.2Spring 2.5Tomcat...
  • usedtolove
  • usedtolove
  • 2009年12月18日 23:23
  • 2240

在Activity中开启一个线程执行网络操作出现的问题

由于项目需要,在Launcher中需要定位当前的城市,使用的方法是利用新浪提供的网址来获得城市。...
  • hanhan1016
  • hanhan1016
  • 2016年04月25日 17:06
  • 1090

Java类加载器(Class Loader)之详解

本文主要总结一下我对Java类加载器(Class Loader)认识,如有不准确之处还望大侠不吝赐教! 关键字:Java,类加载器(Class Loader) 主要从如下几个部分进行介绍: ...
  • Radic_Feng
  • Radic_Feng
  • 2011年10月23日 18:31
  • 8204

Android studio异常Class not found using the boot class loader; no stack available

01-16 01:50:58.298 9057-9057/? E/AndroidRuntime: FATAL EXCEPTION: main ...
  • sinat_35670989
  • sinat_35670989
  • 2017年01月16日 15:09
  • 3710
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:浅析Context Class Loader
举报原因:
原因补充:

(最多只允许输入30个字)