接https://blog.youkuaiyun.com/guzhangyu12345/article/details/84666423 的最后例子,运行时会报如下错误:
[quasar] ERROR: while transforming java/util/IdentityHashMap$KeyIterator: null
java.lang.IllegalArgumentException
at co.paralleluniverse.fibers.instrument.QuasarInstrumentor.getMethodDatabase(QuasarInstrumentor.java:181)
at co.paralleluniverse.fibers.instrument.QuasarInstrumentor.instrumentClass(QuasarInstrumentor.java:108)
at co.paralleluniverse.fibers.instrument.QuasarInstrumentor.instrumentClass(QuasarInstrumentor.java:94)
at co.paralleluniverse.fibers.instrument.JavaAgent$Transformer.transform(JavaAgent.java:209)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
at java.util.IdentityHashMap$KeySet.iterator(IdentityHashMap.java:977)
at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:101)
at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46)
at java.lang.Shutdown.runHooks(Shutdown.java:123)
at java.lang.Shutdown.sequence(Shutdown.java:167)
at java.lang.Shutdown.shutdown(Shutdown.java:234)
[quasar] ERROR: while transforming java/util/IdentityHashMap$IdentityHashMapIterator: null
java.lang.IllegalArgumentException
at co.paralleluniverse.fibers.instrument.QuasarInstrumentor.getMethodDatabase(QuasarInstrumentor.java:181)
at co.paralleluniverse.fibers.instrument.QuasarInstrumentor.instrumentClass(QuasarInstrumentor.java:108)
at co.paralleluniverse.fibers.instrument.QuasarInstrumentor.instrumentClass(QuasarInstrumentor.java:94)
at co.paralleluniverse.fibers.instrument.JavaAgent$Transformer.transform(JavaAgent.java:209)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
at java.util.IdentityHashMap$KeySet.iterator(IdentityHashMap.java:977)
at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:101)
at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46)
at java.lang.Shutdown.runHooks(Shutdown.java:123)
at java.lang.Shutdown.sequence(Shutdown.java:167)
at java.lang.Shutdown.shutdown(Shutdown.java:234)
从堆栈分析,从at java.util.IdentityHashMap$KeySet.iterator(IdentityHashMap.java:977) 到transform是一个跳跃,百思不得其解
堆栈最顶端报错的原因是classLoader为空
transform是对字节码的修改,附: ClassLoader javaagent相关的知识:
代理 JAR 文件的清单必须包含
Premain-Class属性。此属性的值是代理类 的名称。代理类必须实现公共静态premain方法,该方法的原理与main应用程序入口点类似。在 Java 虚拟机 (JVM) 初始化后,每个premain方法将按照指定代理的顺序调用,然后将调用实际的应用程序main方法。每个premain方法必须按照依次进行的启动顺序返回。
premain方法有两种可能的签名。JVM 首先尝试在代理类上调用以下方法:public static void premain(String agentArgs, Instrumentation inst);如果代理类没有实现此方法,那么 JVM 将尝试调用:
public static void premain(String agentArgs);如果代理在 VM 启动之后启动,那么代理类还有一个要使用的
agentmain方法。如果是使用命令行选项启动代理,那么agentmain方法将不会被调用。代理类将被系统类加载器加载(参见
ClassLoader.getSystemClassLoader)。系统类加载器是通常加载包含应用程序main方法的类的类加载器
查看quasar的agent类co.paralleluniverse.fibers.instrument.JavaAgent的相关代码,可以看到其加了一个Transformer,根据jdk的注释:the transformer will be called for every new class definition and every class redefinition. Retransformation capable transformers will also be called on every class retransformation
联想到shutdown时可能触发了new class definition,通过代码分析,触发了java/util/IdentityHashMap$KeyIterator的class define,而该线程Thread[DestroyJavaVM,5,main]不存在对应的ClassLoader,所以会报这个错误。
Quasar JavaAgent字节码修改错误解析

本文深入分析了在使用Quasar框架时,JavaAgent在进行字节码修改过程中遇到的IllegalArgumentException错误原因。详细解释了在Java虚拟机关闭时,由于ClassLoader为空导致的错误,并探讨了JavaAgent的工作原理及与类加载过程的关系。
890

被折叠的 条评论
为什么被折叠?



