繁体   English   中英

ClassTransformer没有执行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM