仪器removeTransformer在不同的线程中不起作用

时间:2017-07-04 03:12:01

标签: java javaagents

我正在尝试将该仪器学习到addTransformer,removeTransformer和reTransformer。

我尝试添加变压器,效果很好。

当我在添加变压器之后移除变压器时,它也可以正常工作。

 public static void premain(String agentArgs, Instrumentation instrumentation) {
    ClassFileTransformer transformer = new ClassFileTransformer() {
        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
            if (!className.contains("Test")) {
                return classfileBuffer;
            }
            ClassReader cr = new ClassReader(classfileBuffer);

            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
            cr.accept(new FieldAdapter(cw, new FieldNode(ASM5, Opcodes.ACC_PRIVATE, "hello", Type.getDescriptor(String.class), "test", "first")), 0);
            return cw.toByteArray();
        }
    };

    instrumentation.addTransformer(transformer, true);
    instrumentation.removeTransformer(transformer);
  }

但是当我尝试在不同的线程中删除变换器时,它不起作用。

public static void premain(String agentArgs, Instrumentation instrumentation) {
    ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    ClassFileTransformer transformer = new ClassFileTransformer() {
        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
            if (!className.contains("Test")) {
                return classfileBuffer;
            }
            ClassReader cr = new ClassReader(classfileBuffer);

            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
            cr.accept(new FieldAdapter(cw, new FieldNode(ASM5, Opcodes.ACC_PRIVATE, "hello", Type.getDescriptor(String.class), "test", "first")), 0);
            return cw.toByteArray();
        }
    };
    instrumentation.addTransformer(transformer, true);

    executor.scheduleAtFixedRate(new RemoveTransform(instrumentation, transformer), 3, 10, TimeUnit.SECONDS);
}
static class RemoveTransform implements Runnable {
    private Instrumentation instrumentation;
    private ClassFileTransformer classFileTransformer;
    public RemoveTransform(Instrumentation instrumentation, ClassFileTransformer classFileTransformer) {
        this.instrumentation = instrumentation;
        this.classFileTransformer = classFileTransformer;
    }

    public void run() {
        System.out.println("removed transform.....");
        instrumentation.removeTransformer(classFileTransformer);
    }
}

我通过输出检查,我确定执行删除变换器的线程。

1 个答案:

答案 0 :(得分:0)

删除变换器时,这并不意味着已经在重置时转换为旧状态的类。为此,您必须显式重新转换已加载的类。我假设在你的第一个例子中,在删除变换器之后加载了有问题的类,而在第二个例子中这不再是真的。

可以从任何线程中删除类文件转换器。