Search code examples
javajavassist

Using Javassist to instrument a private method of a parent class?


I would like to use Javassist to instrument a Java class which source is out of my control (Java 1.6.0_26-b03, Javassist 3.16.1-GA).

I'm relatively new to Javassist, but think I know the concepts behind it. I read a lot about it, but maybe I missed something. Please, see the following, really simple code:

File ParentPrivateMethodInstrumentingTest.java:

package test.javassist;

import javassist.*;

public class ParentPrivateMethodInstrumentingTest
{
    public ParentPrivateMethodInstrumentingTest() throws Exception
    {
        ClassPool classPool = ClassPool.getDefault();

        CtClass childCtClass = classPool.get( "test.javassist.Child" );
        CtMethod parentCtMethod = childCtClass.getMethod( "parent", "()V" );

        parentCtMethod.insertBefore( "{ System.err.println( \"-- before parent() --\" ); }" );

        Child child = (Child)childCtClass.toClass().newInstance();
        child.parent();
    }

    public static void main( String[] args ) throws Exception
    {
        new ParentPrivateMethodInstrumentingTest();
    }
}

File Parent.java:

package test.javassist;

public class Parent
{
    private void privateParent()
    {
        System.out.println( "Parent.privateParent()" );
    }

    public void parent()
    {
        System.out.println( "Parent.parent()" );
        privateParent();
    }
}

File Child.java:

package test.javassist;

public class Child extends Parent
{

}

When I run this program, the output is:

Parent.parent()
Parent.privateParent()

So my question is, why is there no line "-- before parent() --", which I thought has been inserted into the bytecode?

Is it not possible to do code insertions the way I've tried on private methods of parent classes?

Thanks a lot for your help!


Solution

  • Thanks to the help of the author of the Framework, I got a hint where the problem lies and I would like to share the solution here. Since I modify a method of a parent class, that class must be also loaded with

    childCtClass.getSuperclass().toClass();
    

    right after the line

    parentCtMethod.insertBefore
    

    My thanks go to Prof. Shigeru Chiba.