怎么定位微服务启动时 AppClassLoader 与 ExtensionClassLoader 的加载边界

云雪吖_4935

云雪吖_4935

2026-05-19

477人浏览

原创

appclassloader与extensionclassloader的边界由jvm启动参数和目录结构决定:前者加载-classpath路径(含boot-inf/classes及lib),后者加载$java_home/jre/lib/ext或-djava.ext.dirs指定路径;验证需结合jps -lvm、-verbose:class及类加载器打印。

怎么定位微服务启动时 appclassloader 与 extensionclassloader 的加载边界

微服务启动时,AppClassLoader 和 ExtensionClassLoader 的加载边界,本质上是 类路径(class path)与扩展路径(ext path)的物理分界,不是靠代码逻辑判断,而是由 JVM 启动参数和目录结构决定的。定位关键在于搞清“谁加载了哪个类”以及“为什么是它加载”。


一、明确两者的默认加载范围

  • ExtensionClassLoader
    加载 $JAVA_HOME/jre/lib/ext(或通过 -Djava.ext.dirs 指定)目录下的 JAR/CLASS 文件;
    例如:junit-platform-launcher-1.10.0.jar 若放在此目录,就会被 ExtensionClassLoader 加载。

  • AppClassLoader(也叫 System ClassLoader)
    加载 -classpath(或 -cp)或 CLASSPATH 环境变量指定的所有路径,包括:

    • BOOT-INF/classes/(Spring Boot Fat Jar 内部)
    • BOOT-INF/lib/*.jar 中的非 META-INF/MANIFEST.MF 声明为 Class-Path 的依赖(实际由 AppClassLoader 加载)
    • 显式传入的 -cp lib/a.jar:classes/

✅ 注意:Spring Boot 的 LaunchedURLClassLoader 是 AppClassLoader 的子类,但它不改变双亲委派链——仍把请求先交给 ExtensionClassLoader,再往上到 Bootstrap。


二、运行时快速定位加载器归属

用以下任意一种方式,在微服务启动初期(如 @PostConstruct 或 SpringApplicationRunListener)打印类的加载器:

System.out.println("String loaded by: " + String.class.getClassLoader()); // null → Bootstrap
System.out.println("JunitPlatformRunner loaded by: " + 
    org.junit.platform.launcher.core.LauncherFactory.class.getClassLoader());
System.out.println("YourAppConfig loaded by: " + 
    com.example.MyAppConfig.class.getClassLoader());
  • 输出为 null:Bootstrap 加载(如 java.lang.*)
  • 输出形如 sun.misc.Launcher$ExtClassLoader@...:ExtensionClassLoader
  • 输出形如 sun.misc.Launcher$AppClassLoader@... 或 org.springframework.boot.loader.LaunchedURLClassLoader@...:AppClassLoader 或其子类

三、验证 classpath/ext 目录是否被篡改

检查 JVM 启动参数(可通过 jps -lvm 或查看进程启动命令):

# 典型 Spring Boot 启动命令中应不含:
-Djava.ext.dirs=...         # ⚠️ 若出现,说明人为重置了 ext 路径,边界已偏移
-Djava.endorsed.dirs=...    # (已废弃,但仍有项目误用)

# 应关注:
-cp /path/to/app.jar        # AppClassLoader 主力路径
-Dloader.path=lib/         # Spring Boot 特有,仍归 AppClassLoader 管理

若发现 -Djava.ext.dirs 被显式设置,哪怕只加了一个空格路径,JVM 就会完全忽略默认 $JAVA_HOME/jre/lib/ext,此时所有 ext 类必须出现在你指定的路径里,否则加载失败。

SSL Certificate Monitor
SSL Certificate Monitor

检查一个或多个域名的 SSL/TLS 证书到期时间、颁发者、协议及 SAN 信息,用于应要求检查证书、监控到期或验证 HTTPS 等场景。

下载

四、用 -verbose:class 观察实时加载过程

启动微服务时加上 JVM 参数:

-javaagent:your-agent.jar -verbose:class -XX:+TraceClassLoadingPreorder

启动后搜索关键词:

  • [Loaded javax.servlet.http.HttpServlet from ...] → 查看 from 后的路径,匹配是否在 lib/ext/ 下
  • [Loaded com.example.MyService from file:/app.jar!/BOOT-INF/classes/] → 明确属于 AppClassLoader
  • 若某类报 ClassNotFoundException 且路径明显在 ext/ 下,但没被加载 → 检查该 JAR 是否缺失 META-INF/MANIFEST.MF 或签名异常(ext 目录下 JAR 有更严格校验)

? 小技巧:临时把一个测试类打包进 ext/xxx.jar,再启动并 Class.forName("TestInExt"),看是否成功 —— 成功即证明 ExtensionClassLoader 生效且路径可达。


AppClassLoader 与 ExtensionClassLoader 的边界,不在代码里写死,而在 JVM 启动那一刻就由目录和参数划定了。真正要做的,是看清启动参数、确认物理路径、用 -verbose:class 验证行为 —— 不复杂但容易忽略细节。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10277

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7402

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6492

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1124

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

928

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1356

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2709

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20011

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1195

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 0.1万人学习

Kratos框架v3文档
Kratos框架v3文档

共0课时 | 0人学习