java - ASM 字节码替换功能未完成

标签 java java-native-interface bytecode java-bytecode-asm javaagents

我有一个稍微复杂的体系结构,我在其中尝试使用 JVMTI 函数检测类 RetransformClasses和事件 Hook ClassLoadFileHook ,同时使用JNI上到Java空间进行转换。在 ClassLoadFileHook 中,我检查它是否为我想要检测的类触发,如果是,我对 Java 类进行 JNI 调用,在该类中我使用 ASM 5.0.4 执行检测。 .也就是说,在 Java 空间中,我得到一个表示检测类的字节数组,然后回调到我的 native 代码以应用更新。

我遇到的问题是,在我重新转换类的 Java 代码中,代码在我实例化 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 block 也不会执行。我不确定这里会发生什么——为什么实例化一个采用通用字节数组的 ClassReader 会导致代码像这样挂起?我实际上没有对类进行任何操作。

最佳答案

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

关于java - ASM 字节码替换功能未完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40346122/

相关文章:

java - Swing 和线程

java - 缓冲图像找不到文件

java - 使用 GSON 解析 JSON 文件

android - 将字节码转换为 dex Android studio 时出错

java - 正则表达式匹配 "path/*.extension"

java-native-interface - jni 和在 Java 中使用 C++ 新对象

c++ - JNI 使用多线程从 C++ 调用 Java

Java 字节码、java Supplier 和 invokedynamic 参数

java - javassist 是否允许修改条件表达式中的运算符?

android - 如何使用 productflavors 和 jni 设置 Android 库模块