仪器removeTransformer在不同线程中不工作
问题描述:
我正在尝试学习仪器以添加变形器,removeTransformer和reTransformer。仪器removeTransformer在不同线程中不工作
我试图添加变压器,它运作良好。
当我添加变压器后,如下图所示,除去变压器,它也很好。
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);
}
}
我检查了输出,我肯定是移除变压器执行的线程。
答
当你移除一个变压器时,这并不意味着那些已经在复位时转换到旧状态的类。要发生这种情况,您必须显式重新转换已经加载的类。我假设在你的第一个例子中,所讨论的类在变换器被移除后被加载,而在第二个例子中这不再是真的。
类文件转换器可以从任何线程中删除。
你的意思是我必须重新转换添加inteceptor的类? –
这是正确的。 –
但是在添加'instrumentation.retransformClasses(Test.class);'removeTransformer之后它仍然不起作用?你有一个演示与我分享? –