[英]ClassTransformer not executing
使用案例
我正在尝试编写Java SE8 ClassFileTransformer
实现。 这个目标是调试。 我很清楚BTrace,但它并不适合我正在尝试做的事情。 那是什么,是内部方法水平检查。 BTrace将其断点限制为进入/退出。 我想了解一下这个细节。
所以我想我现在用ASM做这件事现在很难吗?
( ASM是ByteBuddy和BTrace使用的字节代码操作库)
问题
所以我开始定义一个简单的ClassFileTransformer
。
public class PreMainInjection {
public static void premain(String agentArgs,
Instrumentation inst) {
inst.addTransformer(new EntryPoint(), true);
}
}
public class EntryPoint implements ClassFileTransformer {
public EntryPoint() { }
@Override
public byte[] transform(ClassLoader classloader, String name,
Class<?> clazz, ProtectionDomain prot, byte[] data) {
System.out.printf("Loaded: %s\n", name);
}
}
这非常有效:DI看到所有类的列表作为我正在检查的应用程序开始。
所以现在我带来了ASM。
public class PreMainInjection {
public static void premain(String agentArgs,
Instrumentation inst) {
inst.addTransformer(new EntryPoint(), true);
}
}
public class EntryPoint implements ClassFileTransformer {
public EntryPoint() { }
@Override
public byte[] transform(ClassLoader classloader, String name,
Class<?> clazz, ProtectionDomain prot, byte[] data) {
ClassReader reader = new ClassReader(bytes);
ClassNode node = new ClassNode();
ClassWriter writer = new ClassWriter(
ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
reader.accept(node, ClassReader.EXPAND_FRAMES);
System.out.printf("Name: %s", node.name);
node.accept(writer);
return writer.toByteArray();
}
}
这有效...到目前为止我的应用程序没有中断。 但我从来没有看到过单一的调试输出。
那么发生了什么?
如果我的经纪人刚才进一步扩展
System.out.printf("Loaded %s\n", name);
return null;
该应用程序仍然有效,我可以看到输出。 所以我很困惑。
回答你的第一个问题ASM有多难:非常难。
要达到您的实际要点:您可能在到达打印输出之前遇到异常。 对于类文件转换器,如果它们转义transform
方法,则会禁止异常。 您是否尝试将代码包装在try-catch块中以查看是否引发了异常?
您也有可能没有将ASM与您的代理捆绑在一起。 在这种情况下,在变换器执行期间会出现错误而不是异常。 最后,我会尝试你的代理没有帧计算,因为这需要访问所有引用的类文件,这也可能是问题的根源。
所以我似乎遇到了一个奇怪的边缘情况
只有在完成ClassReader
访问后, ClassNode
的内部字段才会被实例化。 在这种情况下,它是静态可证明的System.out.printf("Name: %s", node.name);
将始终在编译时返回NullPointerException
。
所以我认为JVM根本不加载我的ClassFileTransformer
。
无论哪种方式,我都有系统工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.