I have a class code like this:
public class OriginalClass {
@ToInitialize
private TestClass object1;
private TestClass object2;
@MakeProxy
public void publicMethod1() {
privateMethod1();
}
private void privateMethod1() {
object1.doSomething();
}
}
Then I create subclass (proxy) code like this:
Class<?> proxyClass = new ByteBuddy()
.subclass(OriginalClass.class)
.method(ElementMatchers.isAnnotatedWith(MakeProxy.class))
.intercept(MethodDelegation.to(MethodInterceptor.class))
.make()
.load(OriginalClass.getClassLoader())
.getLoaded();
Then I instantiate proxy object:
OriginalClass proxyObject = proxyClass.getDeclaredConstructor().newInstance();
When I invoke publicMethod1() on proxyObject, I get NullPointerException saying that object1 is null.
Can I somehow initialize object1 field ? For example in MethodInterceptor definition ?
Field object2 should not be initialized, because it doesn't have @ToInitialize annotation.
My OpenJDK implementation doesn't support ByteBuddyAgent.install().
Possible solution
I've recently found that this problem can be solved by implementing MethodInterceptor class like this:
public class MethodInterceptor {
@RuntimeType
public static Object intercept(@Origin Class<?> originalClass, @This Object proxyInstance, ...) {
Field[] fields = originalClass.getDeclaredFields();
for (Field field : fields) {
Class<?> fieldType = field.getType();
if (fieldType == TestClass.class) {
if (field.isAnnotationPresent(ToInitialize.class)) {
TestClass object = new TestClass();
try {
field.setAccessible(true);
field.set(proxyInstance, object);
} catch (Exception e) {
...
}
}
}
}
}
}