private void injectClassHandlerToInstrumentedClasses(ClassPool classPool) throws NotFoundException, CannotCompileException { int index; synchronized (CLASS_HANDLERS) { CLASS_HANDLERS.add(classHandler); index = CLASS_HANDLERS.size() - 1; } CtClass robolectricInternalsCtClass = classPool.get(RobolectricInternals.class.getName()); robolectricInternalsCtClass.setModifiers(Modifier.PUBLIC); robolectricInternalsCtClass.getClassInitializer().insertBefore("{\n" + "classHandler = " + AndroidTranslator.class.getName() + ".getClassHandler(" + index + ");\n" + "}"); }
private void addClassInitializerNotification(CtClass clazz) throws CannotCompileException { if (null == clazz.getClassInitializer()) { clazz.makeClassInitializer(); } clazz.getClassInitializer().insertBefore( GlobalNotificationBuildSupport.class.getName() + ".testClassInitiated(" + clazz.getName() + ".class);"); }
/** * Creates a static class initializer that creates the table used in * GET_METHOD */ private void addMethodTableInitializer(CtClass cl, MethodMap methodMap) throws CannotCompileException { CtConstructor initializer = cl.makeClassInitializer(); StringBuilder code = new StringBuilder(); code.append(" {\n"); for (CtMethod methodDescriptor : methodMap.getMethods()) { String methodName = methodMap.getOriginalName(methodDescriptor); CtClass definingClass = methodDescriptor.getDeclaringClass(); String methodId = methodMap.getMethodId(methodDescriptor); List<Class<?>> paramClasses = getParameterClasses(methodDescriptor); String paramArgs = getParameterArg(paramClasses); code.append(" ").append(methodTableName).append(".put(\""); code.append(methodId).append("\", "); code.append(definingClass.getName()).append(".class."); code.append("getDeclaredMethod(\"").append(methodName).append("\", "); code.append(paramArgs).append("));\n"); } code.append(" }\n"); debugPrint("Adding method table %s\n", code); initializer.insertBefore(code.toString()); }
logger.trace(String.format("class file transformer invoked for className: %s\n", className)); ctclz.makeClassInitializer().insertBefore( ReferenceListener.class.getName() + ".addReference(" + ctclz.getName() + ".class);");
public byte[] transform(byte[] classfileBuffer, RuntimeException exception) { int number; synchronized (exceptions) { number = exceptions.size(); exceptions.add(exception); } final String src = JavaAgent.class.getName() + ".dontCall(" + number + ");"; try { CtClass clazz = pool.makeClass(new ByteArrayInputStream(classfileBuffer), false); CtConstructor method = clazz.getClassInitializer(); if (method != null) { method.insertBefore(src); } else { method = CtNewConstructor.make(new CtClass[0], new CtClass[0], src, clazz); method.getMethodInfo().setName("<clinit>"); method.setModifiers(Modifier.STATIC); clazz.addConstructor(method); } return clazz.toBytecode(); } catch (IOException e) { e.printStackTrace(); return null; } catch (CannotCompileException e) { e.printStackTrace(); return null; } } }
staticInitializer.insertBefore(references.initializer());
public byte[] instrumentClassWithStaticStmt(String className, String instrumentationInstruction) throws CannotCompileException, NotFoundException, IOException { ClassPool pool = ClassPool.getDefault(); CtClass clazz = pool.get(className); clazz.defrost(); for (CtConstructor ctConstructor : clazz.getConstructors()) { ctConstructor.insertAfter(instrumentationInstruction); } CtMethod[] methods = clazz.getMethods(); if (methods != null) { for (CtMethod ctMethod : clazz.getMethods()) { if (Modifier.isStatic(ctMethod.getModifiers())) { ctMethod.insertAfter(instrumentationInstruction, true); } } } CtConstructor constructor = clazz.makeClassInitializer(); constructor.insertBefore(instrumentationInstruction); clazz.defrost(); return clazz.toBytecode(); } }