ByteBuddy: Initialize private fields of proxy superclass

Viewed 31

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) {
                        ...
                    }
                }
            }
        }
    }
    
}
0 Answers
Related