You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 9+环境下基于javassist的javaagent模块化访问异常问题

问题解决方案

根因分析

你的问题由两个错误配置共同导致:

  1. Java 9+模块化机制限制:属于java.base命名模块的java.lang.Error,默认无法访问bootstrap类加载器加载的未命名模块中的代理类,即便添加了--add-reads指定自定义模块也无效,因为你把代理包放在了bootclasspath下,实际加载到的是未命名模块的类,不是你配置的sg.agent命名模块。
  2. 重复类加载冲突:你同时将代理包配置到-Xbootclasspath/a和--module-path下,导致同一个代理类被bootstrap类加载器和应用类加载器各加载一次,最终触发Jetty启动时的重复类定义报错。

修复步骤

步骤1:清理冗余启动参数

删除以下错误配置的启动参数:

  • --module-path path-to-agent-jar-folder
  • --add-modules sg.agent
  • --add-modules java.base
    保留两个基础参数:
  • -Xbootclasspath/a:"path-to-agent.jar"
  • -javaagent:path-to-agent.jar

步骤2:添加正确的模块化权限参数

新增启动参数--add-reads java.base=ALL-UNNAMED,直接授予java.base模块对bootstrap类加载器持有的所有未命名模块类的访问权限,适配你将代理包放在bootclasspath的加载逻辑。

步骤3:修复Javassist类找不到问题

你当前栈中Javassist编译报错,是因为Javassist默认的类池未加载到bootstrap路径下的代理类,需要在ErrorClassTransformer.transform方法中,执行插桩代码前手动补充类路径:

ClassPool classPool = ClassPool.getDefault();
// 追加bootstrap类加载器的类路径,null代表bootstrap加载器
classPool.appendClassPath(new LoaderClassPath(null));

步骤4:清理Manifest冗余配置

删除代理Jar包Manifest文件中的以下配置项,这些模块化配置只适用于命名模块加载场景,和你当前的bootclasspath加载逻辑冲突:

  • Automatic-Module-Name: sg.agent
  • Add-Exports: module/package
  • Add-Opens: module/package

步骤5:验证最终启动参数

调整后的完整启动参数仅保留3项:

-Xbootclasspath/a:"path-to-agent.jar"
-javaagent:path-to-agent.jar
--add-reads java.base=ALL-UNNAMED

启动后即可正常完成java.lang.Error的插桩,也不会出现Jetty重复类加载的问题。

内容的提问来源于stack exchange,提问作者Srinivas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:27:03