Search code examples
javaclassloaderinstrumentationjavassist

javassist: Rename classes and Fields types


I'm working on a project which needs instrumentation of classes. I'm using javassist because it is very handy to do instrumentation in my case.

I'm facing a problem, which can be described using following code snippet:

Suppose Class 1:

public class Class1 {
    Class2 class2;
}

And Class 2:

public class Class2 {
    //Code
}

And a function for getting CtClasses from from the defined classes and to do some code transformation.

public void testFunction() throws NotFoundException {
        ClassPool classPlool;
        classPlool = ClassPool.getDefault();
        CtClass ctCls1 = classPlool.getAndRename("Class1", "Class1_V1");
        // instrument and load ctCls1 etc.
        CtClass ctCls2 = classPlool.getAndRename("Class2", "Class2_V1");
        // instrument and load ctCls1 etc.
    }

As, I'm renaming the classes, so the field Class2 class2 in Class1 is of type class Class2, but that class is renamed to Class2_V1. I want to rename the field type also from LClass2 to LClass2_V1.

The ctCls1 is: javassist.CtClassType@3b9a45b3[changed public class Class1_V1 fields=Class1_V1.class2:LClass2;, constructors=javassist.CtConstructor@568db2f2[public Class1_V1 ()V], methods=]

PS: I've to load two versions of classes with different instrumentation, so it's the best way in my case. Moreover, I've searched for the problem, but there is no solution to address it, like this link describes to rename the fields, but not type.


Solution

  • According to Javassist documentation:

    A new class can be defined as a copy of an existing class. The program below does that:

    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("Point");
    cc.setName("Pair");
    

    This program first obtains the CtClass object for class Point.

    Then it calls setName() to give a new name Pair to that CtClass object.

    After this call, all occurrences of the class name in the class definition represented by that CtClass object are changed from Point to Pair. The other part of the class definition does not change.

    EDIT: In order to rename a field type in a class you can navigate the class and get it through the Javassist type CtField

    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.get("Class1");
    CtField cf = cc.getField("class2NameIntoClass1");
    CtClass cc2 = cf.getType();
    cc2.setName("Class2NewName");