ASM 字节码替换功能未完成

ASM Bytecode replacement function not completing

我有一个稍微复杂的架构,我试图在其中使用 JVMTI 函数 RetransformClasses, and event hook ClassLoadFileHook, while using JNI to go up to Java space to perform the transformation. In ClassLoadFileHook, I check if it's being fired for the class I want to instrument, and if so, I make a JNI call to a Java class where I perform the instrumentation using ASM 5.0.4 检测 class。也就是说,在 Java space 中,我得到一个表示已检测 class 的字节数组,然后回调到我的本机代码以应用更新。

我遇到的问题是,在我的 Java 代码中,我重新转换 class,代码挂起 during/after 我实例化了 ClassReader

/**
 * Transform some class and then call back down to native code to apply
 * the transformation.
 *
 * @param existingClass The existing class to change.
 */
public synchronized void transformSomeClass(byte[] existingClass) {
    System.out.println("Transformation function started. Existing class len: " + existingClass.length);
    try {
        ClassReader cr = new ClassReader(existingClass);
        // No statements below here are being executed.
        // I'm also not sure if `new ClassReader` is being successfully
        // executed.
        System.out.println("After ClassReader instantiation");
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        System.out.println("After ClassWriter instantiation");
        ClassVisitor cv =
                new MyCustomClassAdapter(cw, this.lineNumberToPlaceUpdate_);
        System.out.println("After ClassVisitor instantiation");
        cr.accept(cv, 0);
        System.out.println("After cv accept.");

        System.out.println("Applying class transformation natively.");
        // Call back down to native code to apply the update in ClassLoadFileHook.
        applyClassTransformNative(cw.toByteArray());
        System.out.println("Transformation function ended.");
    } catch (Exception e) {
        // This is never being fired.
        System.err.println("Class transformation could not be completed. Error message: " + e.getMessage());
        e.printStackTrace();
    } finally {
        // This print statement is never executed.
        System.err.println("Going back to native code from finally");
    }
}

正如我在代码注释中提到的,在 ClassReader 实例化语句之后什么都没有执行。即使 finally 块也不会执行。我不确定这里会发生什么——为什么实例化一个采用通用字节数组的 ClassReader 会导致代码像这样挂起?我实际上没有对 class.

执行任何操作

如果您调用 Java 代码导致 class 加载,则您在加载 class 的 class 加载器上隐式同步。我假设你在原生层触发了这样一个 class 加载,然后当你试图在 Java 层再次触发它时被阻止。这就是为什么当您尝试转换 Java 中的 class 时,您永远不会超越第一个 ASM class。