用例
我正在尝试编写 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);
}
}
这工作得很好:D 当我正在检查的应用程序启动时,我看到了所有类的列表。
所以现在我引入了 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 block 中以查看是否引发异常?
也有可能您没有将 ASM 与您的代理捆绑在一起。在这种情况下,在转换器执行期间您会收到错误而不是异常。最后,我会尝试不使用帧计算的代理,因为这需要访问所有引用的类文件,这也可能是问题的根源。
关于java - ClassTransformer 未执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44123894/