简体   繁体   English

ClassTransformer没有执行

[英]ClassTransformer not executing

USE CASE 使用案例

I'm attempting to write a Java SE8 ClassFileTransformer implementation. 我正在尝试编写Java SE8 ClassFileTransformer实现。 The goal of this is Debugging. 这个目标是调试。 I'm well aware of BTrace but it doesn't really fit the bill for what I'm trying to do. 我很清楚BTrace,但它并不适合我正在尝试做的事情。 What that is, is internal method level inspection. 那是什么,是内部方法水平检查。 BTrace limits its breakpoints to entry/exit. BTrace将其断点限制为进入/退出。 I wanted to get into the details of this. 我想了解一下这个细节。

So I figured I'd do this myself with ASM now hard can it be? 所以我想我现在用ASM做这件事现在很难吗?

( ASM is a byte code manipulation library used by ByteBuddy and BTrace) ASM是ByteBuddy和BTrace使用的字节代码操作库)


PROBLEM 问题

So I started by defining a simple ClassFileTransformer . 所以我开始定义一个简单的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);
    }
}

And this worked perfectly :DI see a list of all the classes as the application I'm inspecting start. 这非常有效:DI看到所有类的列表作为我正在检查的应用程序开始。

So now I bring in ASM. 所以现在我带来了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();
    }
}

This works... so far as my app doesn't break. 这有效...到目前为止我的应用程序没有中断。 But I never see a single debug output. 但我从来没有看到过单一的调试输出。

So what is going on? 那么发生了什么?

To expand further if my agent just does 如果我的经纪人刚才进一步扩展

 System.out.printf("Loaded %s\n", name);
 return null;

The app still works and I can see the outputs. 该应用程序仍然有效,我可以看到输出。 So I'm deeply confused. 所以我很困惑。

To answer your first question how hard ASM can be: very hard. 回答你的第一个问题ASM有多难:非常难。

To get to your actual point: you are probably getting an exception before reaching the print output. 要达到您的实际要点:您可能在到达打印输出之前遇到异常。 With a class file transformer, exceptions are suppressed if they escape the transform method. 对于类文件转换器,如果它们转义transform方法,则会禁止异常。 Did you try to wrap the code in a try-catch block to see if an exception is raised? 您是否尝试将代码包装在try-catch块中以查看是否引发了异常?

There is also a chance that you did not bundle ASM with your agent. 您也有可能没有将ASM与您的代理捆绑在一起。 In this case, you would get an error rather than an exception during your transformer's execution. 在这种情况下,在变换器执行期间会出现错误而不是异常。 Finally, I would try your agent without frame computation as this requires access to all referenced class files which can also be a source of problems. 最后,我会尝试你的代理没有帧计算,因为这需要访问所有引用的类文件,这也可能是问题的根源。

So I appear to be hitting a weird edge case 所以我似乎遇到了一个奇怪的边缘情况

ClassNode 's internal fields are only instantiated after a full visit of the ClassReader has been conducted. 只有在完成ClassReader访问后, ClassNode的内部字段才会被实例化。 As that is the case it is statically provable System.out.printf("Name: %s", node.name); 在这种情况下,它是静态可证明的System.out.printf("Name: %s", node.name); will always return a NullPointerException at compile time. 将始终在编译时返回NullPointerException

So I believe the JVM simply doesn't load my ClassFileTransformer . 所以我认为JVM根本不加载我的ClassFileTransformer

Either way I have the system working. 无论哪种方式,我都有系统工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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