Search code examples
javabytecodebyte-buddy

Can I redefine a private method from a parent class using Byte Buddy?


Based on the idea of Can I redefine private methods using Byte Buddy?, I would like to redefine a private method from a parent class. Is that possible? Or it's like the chicken and egg problem ?

Thanks!


Solution

  • Private methods are not dispatched virtually, therefore, you cannot change the dispatch of the private method within the subclass. The only way to do this, would be to hardcode a conditional dispatch into the private method directly.

    You can do so, by using Byte Buddy's Advice class in combination with a Java agent. The Java agent would look like the following:

    new AgentBuilder.Default()
      .disableClassFormatChanges()
      .with(RedefinitionStrategy.REDEFINITION)
      .type(is(ClassWithPrivateMethod.class))
      .transform((builder, type, cl, module) -> {
         return builder.visitor(Advice.to(MyAdvice.class)
                                      .on(named("privateMethod")));
       }).install(inst);
    

    where the code of MyAdvice is inlined in the befinning of the method named privateMethod. The conditional dispatch would look like the following:

    class Adv {
      @OnMethodEnter(skipOn = OnNonDefaultValue.class)
      static boolean intercept(@This ClassWithPrivateMethod self) {
        if (self instanceof ParentClass) {
          // Your code
          return true;
        } else {
          return false;
        }
      }
    }
    

    By returning true and by using the skip coniditon, you only execute the actual code if false is returned.