Firstly, this question is more like a general question than a specific technical problem.
I'm doing a research project, where I need to record all the possible values of public static fields during the test suite execution (The project to run the test suite can be any projects, not written by me, and preferably not change its code). To do this, my plan was to detect the value changes of such public static fields and then serialize those values at the same time.
Specifically, I wanted to use ASM to instrument the java class files to detect such (public-static-)variable-changing instructions and insert some instructions to do the serialization.
However, I noticed that "detect the value change of such public static fields" can be hard and tricky. It is not simply monitoring the PUTSTATIC instruction, because PUTSTATIC only means the reference of that variable is changed (if it is an object), but actually the state (value) of the public static objects can be changed in various ways, e.g., List.add(xxx), List.remove(xxx), and even other user-defined functions of user-defined classes.
For example:
class Name {
String firstName;
String familyName;
public Name(String firstName, String familyName) {
this.firstName = firstName;
this.familyName = familyName;
}
}
class Person {
Name name;
public Person(Name name) {
this.name = name;
}
}
public class Test {
// The following value change (static initializer) can be detected by monitoring 'PUTSTATIC'
public static Person president = new Person(new Name("foo", "bar"));
public void personTest(){
// The object (reference) changed, can be detected by monitoring 'PUTSTATIC'
president = new Person(new Name("xxx", "yyy"));
// The object state changed, but can not be detected by monitoring 'PUTSTATIC'
president.name = new Name("a", "b");
president.name.familyName = "c";
...
}
}
I'm not sure whether it is possible to "record all the possible values of public static fields during test suite execution". Any ideas about this?
someStaticField.foo(), where foo() just causes a log message to be emitted? No? What if foo() deletes a file. Before you say no, note that there is no effective difference between apublic static booleanfield, and deleting/creating a file in a specific location. So why does one 'count' and the other 'does not'?String.hashCode()change the String? It may assign thehashCodefield when first called, after all.record Name(String firstName, String familyName) {}, however, it’s not clear why “serialize every possible state” is an actual goal. If I dopresident.name.familyName = "x"; president.name.firstName = "y";, the intermediate state of having"x"for thefamilyNamebut the oldfirstNamewould last only for some nanoseconds if the serialization wasn’t slowing everything down, so what’s the point of serializing it? I could even go a step further and ask, what’s the significance ofstaticfields in your application?