Is it possible to intercept the class fields when a class is initialized and instance fields when an instance is initialized other than using .constructor and .invokable?
For example, is there a way to match fields that have an annotation and then intercept them on class/instance creation so that their values can be set? For example, I want to inject the fields annotated with @InjectMe before Foo() executes.
package test.Foo;
public class Foo {
@InjectMe
private static String classField;
@InjectMe
private String instanceField;
private String ignoreMe;
public Foo() {
System.out.println(classField);
System.out.println(instanceField);
System.out.println(ignoreMe);
}
}
I've already tried intercepting the contructor to do this but it doesn't work b/c you can't access @This before super is called in order to access the instance fields:
@Test
public void interceptConstructorFailsWithThis() {
new ByteBuddy()
.rebase(TypePool.Default.ofClassPath().describe("test.Foo").resolve(), ClassFileLocator.ForClassLoader.ofClassPath())
.constructor(ElementMatchers.any())
.intercept(MethodDelegation.to(
new Object() {
//Can't use @This here...
public void m(@This Object o) {
System.out.println(o);
}
}
).andThen(SuperMethodCall.INSTANCE))
.make()
.load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION);
//fails with "Type uninitializedThis (current frame,stack[1]) is not assignable to 'java/lang/Object'"
new test.Foo();
}
Also there's no way (that I can find) to intercept static initializers before they run using invokable. The interception runs after the static fields are assigned and after any static block.