Intercepting default constructor with Byte Buddy

后端 未结 1 791
逝去的感伤
逝去的感伤 2021-01-18 18:57

I\'m trying to intercept constructor calls with Byte Buddy, this is my sample code:

package t;

import static net.bytebuddy.dynamic.loading.ClassLoadingStrat         


        
1条回答
  •  甜味超标
    2021-01-18 19:29

    You cannot create a handler for a super method invocation for a constructor. The JVM's verifier ensures that any constructor calls another constructor once and only once. This call must be hard-coded into the method that invokes the constructor.

    Note that this restriction holds for any Java byte code and even for scenarios where one is dealing with MethodHandles. Constructors are the big exception.

    To make your exampel work, you need to invoke the super constructor either before or after the delegation. Note that you cannot access any properties that are defined by this from the interceptor (e.g. by @This or by @SuperCall, it is however possible to read the arguments) if you intercept before calling another constructor.

    For your code example, simply chain the interceptor with a SuperCall such that the invocation becomes hard-coded as shown in the following example code:

    new ByteBuddy().subclass(Object.class)
                   .name("t.Foo")
                   .constructor(any()).intercept(to(new Object() {
                     public void construct() throws Exception {
                       System.out.println("CALLING XTOR");
                     }
                   }).andThen(SuperMethodCall.INSTANCE)) // This makes the difference!
                   .make()
                   .load(Bar.class.getClassLoader(), INJECTION)
                   .getLoaded()
    

    I agree that Byte Buddy should be more informative about this problem. I will add proper runtime handling for this scenario (i.e. the method is no longer considered for binding).

    0 讨论(0)
提交回复
热议问题