Find a way out of the ClassLoader maze (1)

恭喜,恭喜,iMouse爱鼠XP版全面发布测试,苹果手机自动化测试必须 电脑控制苹果手机,免越狱,免签名,自动化测试 阅读详情

Find a way out of the ClassLoader maze

System, current, context? Which ClassLoader should you use?

 

By Vladimir Roubtsov


Printer-friendly version Printer-friendly version | Send this article to a friend Mail this to a friend


Page 1 of 2

 

June 6, 2003

QWhen should I use
Thread.getContextClassLoader()?

A Although not frequently asked, this question is rather tough to correctly answer. It usually comes up during framework programming, when a good deal of dynamic class and resource loading goes on. In general, when loading a resource dynamically, you can choose from at least three classloaders: the system (also referred to as the application) classloader, the current classloader, and the current thread context classloader. The question above refers to the latter. Which classloader is the right one?

One choice I dismiss easily: the system classloader. This classloader handles -classpath and is programmatically accessible as ClassLoader.getSystemClassLoader(). All ClassLoader.getSystemXXX() API methods are also routed through this classloader. You should rarely write code that explicitly uses any of the previous methods and instead let other classloaders delegate to the system one. Otherwise, your code will only work in simple command-line applications, when the system classloader is the last classloader created in the JVM. As soon as you move your code into an Enterprise JavaBean, a Web application, or a Java Web Start application, things are guaranteed to break.

So, now we are down to two choices: current and context classloaders. By definition, a current classloader loads and defines the class to which your current method belongs. This classloader is implied when dynamic links between classes resolve at runtime, and when you use the one-argument version of Class.forName(), Class.getResource(), and similar methods. It is also used by syntactic constructs like X.class class literals (see "Get a Load of That Name!" for more details).

Thread context classloaders were introduced in Java 2 Platform, Standard Edition (J2SE). Every Thread has a context classloader associated with it (unless it was created by native code). It is set via the Thread.setContextClassLoader() method. If you don't invoke this method following a Thread's construction, the thread will inherit its context classloader from its parent Thread. If you don't do anything at all in the entire application, all Threads will end up with the system classloader as their context classloader. It is important to understand that nowadays this is rarely the case since Web and Java 2 Platform, Enterprise Edition (J2EE) application servers utilize sophisticated classloader hierarchies for features like Java Naming and Directory Interface (JNDI), thread pooling, component hot redeployment, and so on.

Why do thread context classloaders exist in the first place? They were introduced in J2SE without much fanfare. A certain lack of proper guidance and documentation from Sun Microsystems likely explains why many developers find them confusing.

In truth, context classloaders provide a back door around the classloading delegation scheme also introduced in J2SE. Normally, all classloaders in a JVM are organized in a hierarchy such that every classloader (except for the primordial classloader that bootstraps the entire JVM) has a single parent. When asked to load a class, every compliant classloader is expected to delegate loading to its parent first and attempt to define the class only if the parent fails.

Sometimes this orderly arrangement does not work, usually when some JVM core code must dynamically load resources provided by application developers. Take JNDI for instance: its guts are implemented by bootstrap classes in rt.jar (starting with J2SE 1.3), but these core JNDI classes may load JNDI providers implemented by independent vendors and potentially deployed in the application's -classpath. This scenario calls for a parent classloader (the primordial one in this case) to load a class visible to one of its child classloaders (the system one, for example). Normal J2SE delegation does not work, and the workaround is to make the core JNDI classes use thread context loaders, thus effectively "tunneling" through the classloader hierarchy in the direction opposite to the proper delegation.

By the way, the previous paragraph may have reminded you of something else: Java API for XML Parsing (JAXP). Yes, when JAXP was just a J2SE extension, the XML parser factories used the current classloader approach for bootstrapping parser implementations. When JAXP was made part of the J2SE 1.4 core, the classloading changed to use thread context classloaders, in complete analogy with JNDI (and confusing many programmers along the way). See what I mean by lack of guidance from Sun?

After this introduction, I have come to the crux of the matter: neither of the remaining two choices is the right one under all circumstances. Some believe that thread context classloaders should become the new standard strategy. This, however, creates a very messy classloading picture if various JVM threads communicate via shared data, unless all of them use the same context loader instance. Furthermore, delegating to the current classloader is already a legacy rule in some existing situations like class literals or explicit calls to Class.forName() (which is why, by the way, I recommend (again, see "Get a Load of That Name!") avoiding the one-argument version of this method). Even if you make an explicit effort to use only context loaders whenever you can, there will always be some code not under your control that delegates to the current loader. This uncontrolled mixing of delegation strategies sounds rather dangerous.

To make matters worse, certain application servers set context and current classloaders to different ClassLoader instances that have the same classpaths and yet are not related as a delegation parent and child. Take a second to think about why this is particularly horrendous. Remember that the classloader that loads and defines a class is part of the internal JVM's ID for that class. If the current classloader loads a class X that subsequently executes, say, a JNDI lookup for some data of type Y, the context loader could load and define Y. This Y definition will differ from the one by the same name but seen by the current loader. Enter obscure class cast and loader constraint violation exceptions.

This confusion will probably stay with Java for some time. Take any J2SE API with dynamic resource loading of any kind and try to guess which loading strategy it uses. Here is a sampling:

 

  • JNDI uses context classloaders
  • Class.getResource() and Class.forName() use the current classloader
  • JAXP uses context classloaders (as of J2SE 1.4)
  • java.util.ResourceBundle uses the caller's current classloader
  • URL protocol handlers specified via java.protocol.handler.pkgs system property are looked up in the bootstrap and system classloaders only
  • Java Serialization API uses the caller's current classloader by default

Those class and resource loading strategies must be the most poorly documented and least specified area of J2SE.

Next page >
Page 1 Find a way out of the ClassLoader maze
Page 2 What is a Java programmer to do?

Printer-friendly version Printer-friendly version | Send this article to a friend Mail this to a friend


 

从苏宁电器到卡巴斯基第02篇:我的本科时光(中) 怎么还分班了呢? 大概是在大二第二学期的时候吧,学院突然通知我们要分班。因为我们目前所有学生都是属于工商管理专业的,而从下个学期开始,就要分为会计、市场营销以及工商管理这三个方向。这还真是打了我一个措手不及,我都不知道还有分班这一回事。不过也没关系,我继续选择我的工商管理就好了。不过,在实际的选择结果上,像会计和工商管理这种学科,选的人自然是占了绝大多数,而选择市场营销的,大概也就是十 阅读详情

相关推荐

别再只会插卡了!用示波器实测SIM卡上电时序与通信波形(附故障排查)

本文深入解析了SIM卡通信的电气信号与时序规则,通过示波器实测波形揭示SIM卡上电时序与通信协议的关键细节。从VCC、CLK、RST、DATA四路信号的协同工作,到ATR(Answer to Reset)的解析,再到常见故障的波形诊断与排查方法,为硬件工程师提供了实用的调试指南。文章还分享了高级调试技巧与现代化工具链搭建建议,帮助提升物联网设备SIM卡通信的可靠性与效率。

weixin_42567279的博客 328

【转】Find a way out of the ClassLoader maze (1)

Find a way out of the ClassLoader maze System, current, context? Which ClassLoader should you use? By Vladimir Roubtsov Printer-friendly version | Mail this to a friend Page 1 of 2 ...

weixin_38170255的博客 159

vivado安装空间与依赖要求:入门须知要点

准备安装Vivado时,需重点关注系统空间和依赖环境的配置。结合vivado安装教程,详细说明最低磁盘要求、内存配置及操作系统兼容性,帮助新手快速搭建开发环境,避免常见安装失败问题。

weixin_34725745的博客 1576

Find a way out of the ClassLoader maze

关于讲类加载的文章向来比较少,一来大多数应用开发者

大白日梦想家的专栏 519

从示波器波形看懂死区:手把手教你调ST MCU的PWM,避免三相桥直通炸管

本文详细解析了如何通过示波器波形判断PWM死区时间,并手把手教你调整STM32高级定时器寄存器,避免三相逆变桥直通炸管。文章涵盖死区时间的本质与风险、STM32配置详解、示波器调试技巧及FOC系统中的特殊考量,帮助工程师优化电机驱动性能与安全性。

weixin_30315723的博客 734

拒绝无意义刷屏,打造高效率热点追踪,极空间部署『TrendRadar』

今天的这个项目确实不错,通过部署在极空间NAS之后,我们就能一直不间断的获取到自己想要看到的新闻或者信息。项目的设置项其实有很多,有兴趣的小伙伴可以在部署之后自己慢慢挖掘~目前年终大促正在火热进行中,极空间NAS不管是新品还是之前在售的畅销型号都有专属的优惠,并且还能叠加国补、平台优惠等福利,享受180天换新以及2年质保服务 ,更有抽奖、晒单等活动,喜欢的小伙伴赶快冲吧!

qq_63499861的博客 2292

Find a way out of the ClassLoader maze (2)

Find a way out of the ClassLoader maze System, current, context? Which ClassLoader should you use?  Summary-->--> Printer-friendly version | Mail this to a friendPage 2 of 2

DeepNightTwo的专栏 1234

如何点亮一颗sensor

要点亮一个sensor需要从,时钟、sensorI2C,供电,reset脚,mipi的配置几个方面一一确认。 reset脚拉高 给sensor的时钟有没有。(目前用到的常为24MHZ) 供电 查看sensor的数据手册,看有几个电源,用示波器量一下是否为手册规定的电压 比如:DVDD 数字电压: AVDD模拟电压 DOVDD芯片引脚出来的电压等为多少。 sensor的I2C能否抓到 将I2C的口对应上,用示波器量取i2c的波形。 检查有应答并且数据正确。读写地址是否正...

weixin_40787463的博客 3648

Find a way out of the ClassLoader maze---走出ClassLoader迷宫

  在上篇文章中,遇到朋友提到上下文加载器的问题。一直有很多疑惑。今天在优快云上正巧看到一篇关于上下文加载器的译文(这方面网上相关的资料真的太少了)。感觉有所启发。于是搜了搜原文。连同译文一块作为收藏。译文来自:http://blog.sina.com.cn/u/4b6047bc0100096v对于类加载器,普通Java应用开发人员不需要了解太多。但对于系统开发人员,正确理解Java的类加载器模...

realsmy---久城的学习室 198

让 ABAP Screen Variant 安稳上车:SHD0 与 SHD0_MANDT 的 Transport 全攻略

摘要: SAP项目常需优化交易码界面,通过SHD0的Transaction Variant和Screen Variant可实现字段精简、默认值预设及权限控制,避免修改标准代码。但跨系统迁移时易出现变式丢失或版本兼容问题。核心概念包括: Screen Variant:针对单个屏幕的字段属性配置(跨Client); Transaction Variant:串联多屏幕变式(分跨Client和Client-specific); 版本差异:4.70/6.x后需区分SHD0(跨Client)与SHD0_MANDT(Cl

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 230

基于YOLO26深度学习框架的文档表格识别系统的算法研究实现方法

本文研究了基于YOLO26深度学习框架的文档表格识别系统实现方法。系统采用YOLO26网络架构,通过数据预处理、模型训练、检测推理和表格分析四个模块实现高效表格识别。研究详细阐述了数据归一化、增强等技术处理,以及采用迁移学习策略优化模型训练过程。实验表明,该系统能有效识别多种表格结构并生成结构化数据,为文档自动化处理提供了可靠解决方案。

一键难忘的博客 972

Find a way out of the ClassLoader maze---走出ClassLoader迷宫 ( 转 )

在上篇文章中,遇到朋友提到上下文加载器的问题。一直有很多疑惑。今天在优快云上正巧看到一篇关于上下文加载器的译文(这方面网上相关的资料真的太少了)。感觉有所启发。于是搜了搜原文。连同译文一块作为收藏。译文来自:http://blog.sina.com.cn/u/4b6047bc0100096v对于类加载器,普通Java应用开发人员不需要了解太多。但对于系统开发人员,正确理解Java的类加载器模型是

esidemayi的专栏 677

Linux 服务器上部署 OpenClaw完整教程

2. 全局安装 OpenClaw 3. 初始化配置 配置模型提供商 方式一:使用配置命令(推荐) 方式二:直接编辑配置文件 在 部分添加: 配置多个模型提供商 如果你使用 Antigravity 本地代理,可以同时配置多个模型: 配置飞书集成 1. 创建飞书应用 访问 飞书开放平台 创建企业自建应用 记录 App ID 和 App Secret 2. 配置应用权限 在飞书开放平台,为应用添加以下权限:重要: 必须使用 长连接(WebSocket) 模式,不要使用 HTTP 回调!在飞书开放

Maynor的博客 5250

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 292

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 349

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 144

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 206

LeetCode Hot 100 二叉树专题(二)3 题(Java)

本篇文章共 3 题:543. 二叉树的直径、102. 二叉树的层序遍历、108. 将有序数组转换为二叉搜索树。 每道题都统一按「① 题目分析 & 解题思路 → ② 常见解法(附代码)及讲解 → ③ 知识点总结」的顺序组织;代码使用 Java 编写,节点定义沿用 LeetCode 默认的 TreeNode。

2401_88612756的博客 368

【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端

上一篇讲了 MCP 的概念:标准协议、三大角色、M+N 替代 M×N。

nice_lcj520的博客 509

JDK 下载安装:装完 Java 提示「不是内部或外部命令」?环境变量没配

JDK 是写 Java 程序必须装的东西。它包含运行 Java 的虚拟机(JRE)和编译 Java 的编译器(javac)——装了它,能跑、.java文件能编译成可执行程序。免费,学习和小规模生产都不花钱。

科小怪的博客 637

Java 集合容器高频面试题全解:HashMap 树化阈值、1.7 死循环与 ConcurrentHashMap 演进(2026 招聘 JD 真题复盘)

HashMap 树化阈值 8 的泊松分布依据、退化阈值 6 的防抖设计、JDK 1.7 头插成环死循环的排查与修复、1.8 尾插后为何仍线程不安全、ConcurrentHashMap 放弃分段锁的原因与 ForwardingNode 协作扩容、computeIfAbsent 死锁陷阱、大集合找重复的场景题选型,附三层追问链自测。题目来源为 38 期公开招聘 JD 样本与字节、拼多多、建行、美团、快手公开面经。

蒙眼过河 348

java框架大全

java框架大全

qq_39326137的博客 184

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 365
上一篇: Inside Class Loaders
下一篇: Find a way out of the ClassLoader maze (2)
DeepNightTwo
博客等级 码龄21年 3粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值