vendredi 17 mars 2017

How does CtMethod affects classloading? CtMethod.insertBefore() is ineffective

Please read along. I have a Lion class that has a method stayLion.

public class Lion {
    //class Variables and methods
    public void stayLion(String temp,int temp2,double temp3, boolean temp4,Food food) throws InterruptedException {
    //method Body
    }
}

The method takes in a Food instance as one of its parameter. Food class has cook method

public class Food{
    public void cook(){
    }
}

I am trying to instrument both these methods, stayLion and cook. The transform method is called for every class that is loaded by JVM.(Correct me if I am wrong) If classname matches with my desired list of classnames, I extract the list of methods, and verify the methodName and its parameter, I find the CtMethod instance for the method I wish to instrument (stayLion and cook).

public byte[] transform(ClassLoader loader, final  String className, Class classBeingRedefined,  ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    //verifying className(fully qualified), if same then,
    ClassPool classPool = ClassPool.getDefault();
    CtClass ctClass = classPool.getCtClass(className.replace("/","."));
    CtMethod[] methods = ctClass.getDeclaredMethods();

    for (CtMethod method : methods) {
        //verifying method (name and parameter)
        method.insertBefore( //some code );
    }
}

However, in the process of verifying parameters for stayLion, the Food class gets loaded and transform method is not called, (I don't know the reason for this. The class loader is same. Why is transform method not called for Food class as it gets loaded?). To overcome this, I explicitly call transform method for Food class (in general, I call transform method everytime a class whose method I wish to instrument is in the parameter list of any other method I also wish to instrument).

transform(loader,"com/here/debugHelper/Food",null,protectionDomain,null);

But this explicit calling of transform method is ineffective. To be precise,

ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.getCtClass(className.replace("/","."));
CtMethod[] methods = ctClass.getDeclaredMethods();

Till here, methods contains list of all methods of Food class. After verifying cook method with no parameter

for (CtMethod method : methods) {
    //verifying method (name and parameter)
    method.insertBefore( //some code );
}

But at this point, method.insertBefore() is ineffective and is not adding any code to the desired method.





Aucun commentaire:

Enregistrer un commentaire