Search code examples
javajavassist

How to know to which object instance a field belongs to in javassist?


I'm trying to develop a application using javassist, which should count the number of writes and reads to a field in an object. However when a field is written to inside the constructor it shouldn't be counted, only reads. My problem is that if I have a constructor that receives an object of the same type as a parameter and a field of that object is affected I want to count that write. However I don't know how to know to which object instance in javassist that field belongs to. For example taking this constructor as example:

Person(Person p) {
        this.firstname = p.firstname;
        p.surname = "";
        this.surname = p.surname;
    }

I want to count the first and third lines as reads, since a read is valid in a constructor. But the only write I want to count is in the second line since it is a write to a field of a different instance of the object.

At the moment I have search the documentation on javassist and can't find a way to find in runtime to which instance a field belongs to. What I have so far is:

for (CtConstructor ctConstructor : ctClass.getDeclaredConstructors()) {
            ctConstructor.instrument(new ExprEditor() {
                public void edit(FieldAccess fa) throws CannotCompileException {
                    replaceFieldAccess(fa, fieldAccess -> fieldAccess.isStatic() || (fieldAccess.getClassName().equals(className) && fieldAccess.isWriter()));
                }
            });
        }

And my problem is in the second condition of the predicate in the lambda function.

The output I'm looking for is Total reads: 2 Total writes: 1, but I either get no writes, or 3 writes and both options are wrong in my problem.


Solution

  • You only know to which object instance a field belongs during the runtime. You need to inject code that verifies it. One possible solution is to inject this code

    if (this != $0) writeCounter++;

    Remember that it is only possible because the field you want to count is an instance and not a static field.