【发布时间】:2015-12-15 09:49:30
【问题描述】:
我一直在尝试使用 Java 代理通过 ASM 应用字节码转换。
我使用premain 方法实现了一个代理,向仪器添加了一个变压器。
我在 .jar 清单中添加了“Premain-Class”行
Premain-Class: <MyAgentPath>
然后我尝试使用代理运行应用程序。
我有一个问题:我的转换器修改了一些方法调用,所以如果不是所有涉及的类也都被修改了,它就无法工作。还有一些类没有被修改,比如“org.apache.commons.math3.util.FastMath”。 当然,我得到了错误:
java.lang.NoSuchMethodError: org.apache.commons.math3.util.FastMath.floor<new_descriptor>
我查看了很多帖子说它可能是引导加载程序,它不知道此类的路径,所以我尝试使用不同的方式添加它:
-
在清单中添加“Boot-Class-Path”行:
Boot-Class-Path: <...>/commons-math3<...>.jar -
使用方法“appendToBootstrapClassLoaderSearch(JarFile)”
inst.appendToBootstrapClassLoaderSearch("<...>/commons-math3<...>.jar"); -
使用 JVM 参数“-Xbootclasspath/a:”
-Xbootclasspath/a:<...>/commons-math3<...>.jar
这些都没有改变任何东西。
我还使用 Instrumentation 类方法 getAllLoadedClasses() 来查看加载了哪些类,以及加载了应用程序进程中涉及的所有类,包括 FastMath。
for(Class<?> clazz : MyAgent.getInstInstance().getAllLoadedClasses()){
buffWrite.write(clazz.getName());
由于“FastMath”类出错并且引导加载程序应该有它的路径,我尝试在同一个包中添加一些对来自其他类的方法的方法调用。似乎问题并没有针对包的每个类显示。
例如:MathUtils 被转换并调用修改后的方法checkFinite(D)V -> checkFinite<new_descriptor>。
所以我猜这个问题与提供给引导加载程序的路径无关。
如果您对正在发生的事情有一些想法,我会很高兴听到的!
【问题讨论】:
标签: java javaagents