lundi 6 septembre 2021

Add a field and change its value dynamically using Javassist

In the example below, I want to execute the super method of class A by not executing the super method of class B. For this, I am using Javassist and I am able to do so with the help of this SO post. But I am unable to pass a value when calling the super method of class A. I have provided a variable name as parameter, while calling hi() of class C in the example below but that is not being referred in the variable myVar that I am generating using Javassist.

The generated output:

Ok thing C MyData
Important thing A null

Expected output:

Ok thing C MyData
Important thing A MyData

Any help will be very much appreciated.

Source Code:

class A {
    public void hi(String first) {
        System.out.println("Want Important thing A " + first);
    }
}

class B extends A {
    public void hi(String second) {
        System.out.println("Don't want TERRIBLE THING B " + second);
        super.hi(second);
    }
}

class C extends B {
    public void hi(String third) {
        System.out.println("Want important thing C " + third);
        super.hi(third);
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        String name = "MyData";
        CtClass cc = ClassPool.getDefault().get("mypackage.B");
        CtMethod m1 = cc.getDeclaredMethod("hi");
        cc.removeMethod(m1);
        CtMethod m2 = CtNewMethod.copy(m1, cc, null);
        CtClass stringVar = ClassPool.getDefault().get("java.lang.String");
        CtField f = new CtField(stringVar , "myVar", cc);
        cc.addField(f);
        m2.setBody("{ /* override method B.hi() body */ return super.hi(myVar);}", "this", m1.getName());
        cc.addMethod(m2);
        cc.toClass();
        C obj = new C();
        obj.hi(name);
    }
}




Aucun commentaire:

Enregistrer un commentaire