`

Classloader委托加载模型的反向问题

    博客分类:
  • jvm
阅读更多

Classloader委托加载模型的反向问题 英文就是 back door around the classloading delegation scheme

当A类引用到B类,那么加载B类的classloader就是当时A的classloader,下面一个例子

 

public class A {
	public static void main(String[] args) {
	     System.out.println("class A loaded by " + A.class.getClassLoader());
	        //在调用下面的语句是,B的class会被加载,而加载器则是加载A的classloader
		 B b = new B();
		 b.methodB();
	}

}

 

public class B {

	public void methodB() {
	     System.out.println("class B loaded by " + B.class.getClassLoader());
	}

}

    上面打印输出如下:

    class A loaded by sun.misc.Launcher$AppClassLoader@192d342
    class B loaded by sun.misc.Launcher$AppClassLoader@192d342

 

    可是假使我们有3个类,A,B,C,  A和C在classpath下面,B不在classpath下面,而在C:\jdk1.6.0_29\jre\lib\ext 

    \classes下面,上代码

 

public class A {
	public static void main(String[] args) {
		System.out.println("class A loaded by " + A.class.getClassLoader());
		B b = new B();
		b.methodB();
	}
	
}

 

public class B {

	public void methodB() {
		System.out.println("class B loaded by " + B.class.getClassLoader());

		C c = new C();
		c.methodc();
	}

}

 

public class C {

	public void methodc() {
		System.out.println("class C loaded by " + C.class.getClassLoader());
	}

}

    将A和C放入C盘根目录,B放入C:\jdk1.6.0_29\jre\lib\ext\classes

进入cmd,执行结果如下

     C:\>java A
class A loaded by sun.misc.Launcher$AppClassLoader@192d342
class B loaded by sun.misc.Launcher$ExtClassLoader@6b97fd

Exception in thread "main" java.lang.NoClassDefFoundError: C
        at B.methodB(B.java:8)
        at A.main(A.java:6)
Caused by: java.lang.ClassNotFoundException: C
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
        ... 2 more

 

之所以出现A和B都加载了,而C加载不了,是因为委托模型不能反向,因为加载B的classloader是ExtClassLoader, 所以接下来的C也由此classloader加载,按照委托模型,ExtClassLoader会先交由BootStrapClassLoader搜其管辖目录搜索然后由本身在在 C:\jdk1.6.0_29\jre\lib\ext\下搜索,即便如果都搜索不到C,也不会交由AppClassloader加载,因为委托模型只能由当前classloader向上不能向下(而这里的C只能由Appclassloader加载)

 

如何能让B加载到C呢?只能变换classloader

修改后的B代码如下

public class B {

	public void methodB() {
		System.out.println("class B loaded by " + B.class.getClassLoader());
		ClassLoader cl = Thread.currentThread().getContextClassLoader();
		System.out.println("the thread context classloader was " + cl);


		try {
			Class clazzc = Class.forName("C", true, cl); 
			Method m = clazzc.getMethod("methodC", null);
			Object obj = clazzc.newInstance();
			m.invoke(obj, null);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

   Every thread has a classloader associated with it . If the thread is a main thread then the class  

   loader associated with it a System Class Loader. 具体Thread.currentThread(). getContextClassLoader

   方法参考文档,在这里他会返回AppClassloader

 

同上方法运行A类在cmd,得到

C:\>java A
class A loaded by sun.misc.Launcher$AppClassLoader@192d342
class B loaded by sun.misc.Launcher$ExtClassLoader@6b97fd
the thread context classloader was sun.misc.Launcher$AppClassLoader@192d342
class C loaded by sun.misc.Launcher$AppClassLoader@192d342

 

 

这种需求哪里会用到?

比如java.sql.Drivermanager是rt.jar中的类,而用户classpath下面的具体driver则是classpath下面的类,则需要用到此方法,具体参见DriverManager.getConnection(x,x,x)方法

也就是说核心类库中调用用户代码之前都需要变更classloader

 

下面文章可以参考:

http://hllvm.group.iteye.com/group/topic/38709

http://stackoverflow.com/questions/13307885/could-you-please-explain-a-code-snippet-in-drivermanager-class-related-to-classl/13308729#13308729

http://stackoverflow.com/questions/1771679/difference-between-threads-context-class-loader-and-normal-classloader

http://www.blogjava.net/lihuaxajh/articles/94371.html

分享到:
评论

相关推荐

    2023最新最全java面试大全及答案

    - 类加载器的双亲委派模型:确保所有类加载请求最终都会委托给`Bootstrap ClassLoader`。 - 运行时数据区:包括堆、栈、方法区、本地方法栈、程序计数器等。 - 垃圾回收:如何判断对象可回收、垃圾回收算法(如...

    java 命名空间 命名规则

    - 当一个类装载器接收到加载类的请求时,它首先会委托给自己的父类装载器来完成加载操作。 - 如果父类装载器能够成功加载类,则返回该类的`Class`对象;如果不能,则由子类装载器尝试加载。 - 这一过程一直向上递归...

    java面试题及答案-非常全面(包括基础、网络、数据结构、算法及IT大厂面经)

    - **双亲委派模型**:由顶层的启动类加载器委托给父类加载器,再由父类加载器委托给子类加载器。 - **自定义类加载器**:可以通过继承`ClassLoader`类来自定义加载过程。 ### NIO - **非阻塞I/O**:与传统的`...

    PhD_Thesis_Cristina_Pinneri.pdf

    PhD_Thesis_Cristina_Pinneri

    Git知识学习(尚硅谷)

    Git知识学习(尚硅谷)

    套筒机械加工工艺规程制订设计.rar

    套筒机械加工工艺规程制订设计.rar

    The First Adventures on Differential Geometry 9789811296178.pdf

    The First Adventures on Differential Geometry 9789811296178

    汽车防误踏油门机构的设计.zip

    汽车防误踏油门机构的设计.zip

    汽车离合器设计.zip

    汽车离合器设计.zip

    基于SpringBoot的文学创作社交论坛(源码+数据库+万字文档+ppt)533

    基于SpringBoot的文学创作社交论坛,系统包含两种角色:管理员、用户主要功能如下。 【用户功能】 1. **首页:** 浏览社交论坛的主要信息。 2. **火车信息:** 阅读和浏览用户发布的文学创作。 3. **公告资讯:** 查看社交论坛发布的重要通知和公告。 4. **后台管理:** - **首页:** 进行后台管理相关操作。 - **个人中心:** 管理个人信息,查看火车票订购历史等。 - **车票预订管理:** 预订文学创作,选择特定的创作者或主题。 - **车票退票管理:** 处理用户对已预订文学创作的退票请求。 5. **个人中心:** 管理个人信息。 【管理员功能】 1. **首页:** 查看社交论坛整体概况。 2. **个人中心:** 修改密码、管理个人信息。 3. **用户管理:** 审核和管理注册用户的信息。 4. **火车类型管理:** 管理文学创作的分类信息。 5. **火车信息管理:** 监管和管理社交论坛上的文学创作信息。 6. **车票预订管理:** 查看和管理用户的文学创作预订情况。 7. **车票退票管理:** 处理用户对已预订文学创作的退票请求。 8. **系统管理:** - **公告资讯:** 发布、编辑和删除系统的通知和公告。 - **关于我们:** 编辑和更新社交论坛的介绍。 - **系统简介:** 提供社交论坛的简要介绍。 - **轮播图管理:** 管理社交论坛首页的轮播图。 二、项目技术 编程语言:Java 数据库:MySQL 项目管理工具:Maven 前端技术:Vue 后端技术:SpringBoot 三、运行环境 操作系统:Windows、macOS都可以 JDK版本:JDK1.8以上都可以 开发工具:IDEA、Ecplise、Myecplise都可以 数据库

    数控铣床主轴箱设计.zip

    数控铣床主轴箱设计.zip

    某电镀废水工艺流程及平面布置图.zip

    某电镀废水工艺流程及平面布置图.zip

    joblib-0.9.0b4-py2.7.egg

    该资源为joblib-0.9.0b4-py2.7.egg,欢迎下载使用哦!

    价值60元的带会员和后台版的域名防红1.19最新免授权开心版

    管理会员制度渠道,掌管多种服务,黑白名单管理邮箱配置生成提醒发送对接易支付进行交易,订单列表,带有各种短网址功能提供接口对接,实现短网址+防红两不误,可自定义多中转域名,自动识别安全网址各种防红数据后台可显,自定义跳转网站 用户端android-ios 会员制度享受,自定义跳转网站,在线充值,我的生成,在线生成,为你的网址提供保护短网址列表接口文档数据显示,编辑我的生成 防红效果全网 在短网址与防红的前提下,为你的网站提供SEO服务以及腾讯相关网站检测的优化 贴吧+短视频平台+ios+android+pc皆正常 安装:上传源码,访问安装。提示授权时,随意填写 6位数字即可

    joblib-0.9.0b3.tar.gz

    该资源为joblib-0.9.0b3.tar.gz,欢迎下载使用哦!

    实时操作系统毕业设计项目内含说明书.zip

    实时操作系统毕业设计项目内含说明书.zip

    python相关学习资源,python

    python

    塑料瓶自动封口机设计.rar

    塑料瓶自动封口机设计.rar

    CarPlay 系统功能介绍,比较专业的文档,告诉我们开发Carplay的时候需要遵循的规则

    内容概要:本文介绍了苹果公司在WWDC19上发布的CarPlay系统的最新进展,主要包括四个方面的改进:不规则形状显示屏支持、多屏显示支持、动态屏幕尺寸调整以及“嘿,Siri”语音助手集成。不规则形状显示屏支持允许开发者为CarPlay定义交互区域,确保内容适应各种非矩形屏幕。多屏显示支持使车辆可以在多个屏幕上同时展示CarPlay界面,如中心控制台和仪表盘,提供导航、音乐播放等不同内容,并支持独立的夜间模式。动态屏幕尺寸调整功能让CarPlay界面可以实时调整大小,以适应不同的驾驶环境或用户需求。最后,“嘿,Siri”功能让用户可以通过语音唤醒Siri,即使在播放音乐时也能无缝交互,系统内置了持续的回声消除和降噪处理,确保语音识别的准确性。; 适合人群:汽车制造商、软件开发者以及对车载信息系统感兴趣的科技爱好者。; 使用场景及目标:①汽车制造商可以根据新的CarPlay特性优化车内娱乐和导航系统的用户体验;②开发者可以利用这些新特性创建更加丰富的车载应用程序;③科技爱好者可以了解最新的车载技术发展趋势。; 其他说明:文档详细描述了CarPlay系统的技术细节,包括语音活动检测器、关键词检测器、回声消除和降噪等功能的工作原理,以及车辆系统的要求,如始终开启的麦克风输入流处理、连续回声消除和降噪等。更多相关信息可参考苹果开发者网站。

    蓝桥杯第十六届省赛真题!

    内容概要:本文档为第十六届蓝桥杯单片机设计与开发项目省赛的程序设计试题说明,面向大学组。文档详细规定了比赛的基本要求、硬件配置、功能描述、性能要求、输出控制、显示功能、按键功能及初始状态。参赛者需要使用指定的单片机竞赛实训平台,完成环境温度、光强、物体运动状态的检测,并通过数码管、LED指示灯、继电器等实现相应的数据显示、状态指示与控制功能。所有程序需在Keil环境下开发,并按要求提交工程文件。 适合人群:具有单片机编程基础的大专院校学生或相关专业技术人员。 使用场景及目标:①掌握单片机编程技能,熟悉传感器数据采集与处理;②学会通过数码管、LED、继电器等实现人机交互界面的设计与实现;③提高对硬件资源的有效利用能力,确保系统的实时性和稳定性。 阅读建议:此资源旨在帮助参赛者理解比赛规则和技术要求,建议仔细阅读各项功能的具体实现细节,特别注意硬件配置、性能指标以及提交规范的要求。同时,在实际操作中要严格按照文档中的规定进行开发和测试,确保作品符合评分标准。

Global site tag (gtag.js) - Google Analytics