diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java index 05477cd..859a222 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java @@ -1,15 +1,9 @@ package com.alibaba.testable.agent.handler; -import com.alibaba.testable.agent.util.ClassUtil; -import com.alibaba.testable.core.util.LogUtil; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldNode; - -import java.io.IOException; -import java.util.Iterator; /** * @author flin @@ -23,26 +17,11 @@ abstract public class BaseClassHandler implements Opcodes { protected String mockClassName; - protected boolean markTransformed(ClassNode cn, String refName, String refDescriptor) { - Iterator iterator = cn.fields.iterator(); - if (iterator.hasNext()) { - if (refName.equals(iterator.next().name)) { - // avoid duplicate injection - LogUtil.verbose("Duplicate injection found, ignore " + cn.name); - return false; - } - } - cn.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, refName, refDescriptor, null, null)); - return true; - } - - public byte[] getBytes(byte[] classFileBuffer) throws IOException { + public byte[] getBytes(byte[] classFileBuffer) { ClassReader cr = new ClassReader(classFileBuffer); ClassNode cn = new ClassNode(); cr.accept(cn, 0); - if (markTransformed(cn, TESTABLE_REF, ClassUtil.toByteCodeClassName(mockClassName))) { - transform(cn); - } + transform(cn); ClassWriter cw = new ClassWriter( 0); cn.accept(cw); return cw.toByteArray(); diff --git a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java index e6215ef..6594751 100644 --- a/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java +++ b/testable-agent/src/main/java/com/alibaba/testable/agent/handler/MockClassHandler.java @@ -40,7 +40,7 @@ public class MockClassHandler extends BaseClassWithContextHandler { @Override protected void transform(ClassNode cn) { - injectGetInstanceMethod(cn); + injectRefFieldAndGetInstanceMethod(cn); for (MethodNode mn : cn.methods) { if (isMockMethod(mn)) { mn.access &= ~ACC_PRIVATE; @@ -61,25 +61,27 @@ public class MockClassHandler extends BaseClassWithContextHandler { /** * add method to fetch singleton instance of this mock class */ - private void injectGetInstanceMethod(ClassNode cn) { + private void injectRefFieldAndGetInstanceMethod(ClassNode cn) { + String byteCodeMockClassName = ClassUtil.toByteCodeClassName(mockClassName); MethodNode getInstanceMethod = new MethodNode(ACC_PUBLIC | ACC_STATIC, GET_TESTABLE_REF, - VOID_ARGS + ClassUtil.toByteCodeClassName(mockClassName), null, null); + VOID_ARGS + byteCodeMockClassName, null, null); InsnList il = new InsnList(); - il.add(new FieldInsnNode(GETSTATIC, mockClassName, TESTABLE_REF, ClassUtil.toByteCodeClassName(mockClassName))); + il.add(new FieldInsnNode(GETSTATIC, mockClassName, TESTABLE_REF, byteCodeMockClassName)); LabelNode label = new LabelNode(); il.add(new JumpInsnNode(IFNONNULL, label)); il.add(new TypeInsnNode(NEW, mockClassName)); il.add(new InsnNode(DUP)); il.add(new MethodInsnNode(INVOKESPECIAL, mockClassName, CONSTRUCTOR, VOID_ARGS + VOID_RES, false)); - il.add(new FieldInsnNode(PUTSTATIC, mockClassName, TESTABLE_REF, ClassUtil.toByteCodeClassName(mockClassName))); + il.add(new FieldInsnNode(PUTSTATIC, mockClassName, TESTABLE_REF, byteCodeMockClassName)); il.add(label); il.add(new FrameNode(F_SAME, 0, null, 0, null)); - il.add(new FieldInsnNode(GETSTATIC, mockClassName, TESTABLE_REF, ClassUtil.toByteCodeClassName(mockClassName))); + il.add(new FieldInsnNode(GETSTATIC, mockClassName, TESTABLE_REF, byteCodeMockClassName)); il.add(new InsnNode(ARETURN)); getInstanceMethod.instructions = il; getInstanceMethod.maxStack = 2; getInstanceMethod.maxLocals = 0; cn.methods.add(getInstanceMethod); + cn.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, TESTABLE_REF, byteCodeMockClassName, null, null)); } /**