Java Asm 修改 jdk 源码中的 ThreadPoolExecutor execute 不能引入 不是 jdk 的包下的类吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gengzi
V2EX    Java

Java Asm 修改 jdk 源码中的 ThreadPoolExecutor execute 不能引入 不是 jdk 的包下的类吗?

  •  
  •   gengzi 2021-01-25 18:05:10 +08:00 2417 次点击
    这是一个创建于 1768 天前的主题,其中的信息可能已经有所发展或是发生改变。

    提示 NoClassDefFoundError 。 还是说需要其他方式

    第 1 条附言    2021-01-25 23:22:44 +08:00
     public void execute(Runnable var1) { // 编译增加的代码 MDC.setContextMap((Map)MDCInheritableThreadLocal.get()); // 本身的源码 if (var1 == null) { NullPointerException var10000 = new NullPointerException(); System.out.println("end"); throw var10000; } else { int var2 = this.ctl.get(); if (workerCountOf(var2) < this.corePoolSize) { if (this.addWorker(var1, true)) { System.out.println("end"); return; } var2 = this.ctl.get(); } // ... } 

    会提示 NoClassDefFoundError: fun/MDCInheritableThreadLocal

    9 条回复    2021-01-27 10:07:12 +08:00
    wsxyeah
        1
    wsxyeah  
       2021-01-25 20:47:15 +08:00 via iPhone
    这些东西是用户机器上的,除非你打包一个 jre 进去
    gengzi
        2
    gengzi  
    OP
       2021-01-25 23:27:21 +08:00
    @wsxyeah 我在启用前使用 Agent,修改 jdk ThreadPoolExecutor execute 的方法,引入的 jar 应该会在运行时加载吧。
    ffutop
        3
    ffutop  
       2021-01-26 09:02:53 +08:00   1
    ThreadPoolExecutor 是被 Bootstrap ClassLoader 加载的。它的加载路径不包括你自定义的 MDCInheritableThreadLocal 。

    可以用 -Xbootclasspath 指定 Bootstrap 加载特定 Jar 包
    或者在 MANIFEST.MF 用 Boot-Class-Path 声明 Jar 包路径
    kingfalse
        4
    kingfalse  
       2021-01-26 09:38:14 +08:00 via Android
    试试 javassist
    fantastM
        5
    fantastM  
       2021-01-26 10:48:36 +08:00
    在启动参数里用 -javaagent 的话,确实是如 #3 说的类加载问题。可以用 arthas 的 sc 、classloader 之类的命令来查看类的加载情况
    gengzi
        6
    gengzi  
    OP
       2021-01-26 10:56:34 +08:00
    @ffutop @fantastM ok,感谢解答。我去瞅瞅
    gengzi
        7
    gengzi  
    OP
       2021-01-26 22:21:26 +08:00
    @ffutop @fantastM 麻烦再咨询下,
    ```
    -javaagent:D:/ideaworkspace/baselog.jar -Xbootclasspath/a:D:/ideaworkspace/baselog.jar
    ```
    当这个键入 idea 中,运行 springboot 工程,提示 NoClassDefFoundError 关于项目中的引入的 jar,那这些 jar 我需要怎么引入。
    fantastM
        8
    fantastM  
       2021-01-27 02:59:44 +08:00   1
    简单回答:可以在 agent 中自定义类加载器,避免遵循 Java 类加载器中的双亲委派模型。

    详细回答:
    JVM 加载类是按照双亲委派模型来执行的,每个类都会优先委托给父类加载器来加载,当父类加载器无法加载类的时候再由子类加载器来加载,因此在 JVM 中加载的类会有一种层级关系。

    在你的例子中 `ThreadPoolExecutor` 会由 BootStrap ClassLoader 加载,参数 -javaagent 指定的 baselog.jar 包默认会由 System ClassLoader 加载,所以你一开始描述的问题原因是:`ThreadPoolExecutor` 类在被 BootStrap ClassLoader 加载之后链接的时候,无法找到需要被 System ClassLoader 加载的 baselog.jar 包里的 `MDCInheritableThreadLocal`。(注意这个问题是发生在链接阶段,这也是 JVM 为什么抛了 `NoClassDefFoundError` 而不是 `ClassNotFoundException` 的原因)

    然后你将 baselog.jar 包指定为由 BootStrap ClassLoader 加载,这样的话,`ThreadPoolExecutor` 类在被 BootStrap ClassLoader 加载、链接、初始化的时候,就可以找到同样是被 BootStrap ClassLoader 加载的 `MDCInheritableThreadLocal` 了。

    你在 #7 里说的事情,我理解为是你在 baselog.jar 包里用到了「项目中的引入的 jar 」(可能是 Spring 之类的吧),这部分包不由是 BootStrap ClassLoader 加载的,可能是 System ClassLoader,也可能是 Tomcat 的 Webapp ClassLoader,所以自然也会有 `ClassNotFoundException` 的问题。解决方案的话,我不建议把这类包也指定为由 BootStrap ClassLoader 来加载,更好的解决方案是自定义类加载机制,破坏一下 Java 类加载器中的双亲委派模型。

    具体实现的话,可以借鉴一些分布式追踪 APM 系统,它们在采集应用的数据时候,使用的无侵入式方案也是 javaagent,也会对项目中的一些代码做改造。

    一些可供查阅的资料:
    https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html
    https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html
    gengzi
        9
    gengzi  
    OP
       2021-01-27 10:07:12 +08:00
    @fantastM 听君一席话胜读十年书。昨天在查阅资料时,也考虑使用自定义的类加载器来尝试,我再去看看这块内容。非常感谢这么详细的解答。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2399 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 00:21 PVG 08:21 LAX 16:21 JFK 19:21
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86