Search code examples
javassist

Can't update a class method with javassist


I'm playing with javassist (to use it later on a project) but I don't manage to make a simple update to a class. I try to insert code before a method but its not being executed.

I've a gradle project and I'm using javassist version: '3.27.0-GA'.

Given the following class:

public class Dummy{
    public int dummy(){
            return 5;
        }
}

The following test fails, so the class is not being modified:

@Test
public void modifyReturnValueTest() throws NotFoundException, CannotCompileException, IOException {
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("Dummy");
    CtMethod m = cc.getDeclaredMethod("dummy");
    m.insertBefore("{ if(true) return 3; }");
    cc.writeFile();

    assertEquals(3, new Dummy().dummy());
}

I'm missing something?


Solution

  • My guess is that when you call new Dummy().dummy() in

    assertEquals(3, new Dummy().dummy());
    

    the class loader loads the original version of Dummy class.

    Since you want to load/use the version that you modified represented by the CtClass instance cc, you can insert the following snippet before assertEquals to make the class loader load the modified version of the Dummy class instead:

    cc.toClass();
    

    then the assert should be successful.

    Note that in order to use toClass() above we rely on the fact that the Dummy class is never loaded before the toClass() invocation. (It will throw exception otherwise, the class loader cannot load two different versions of the same class at the same time)

    You can check the javassist documentation for more details. This section might be especially useful http://www.javassist.org/tutorial/tutorial.html#load.