byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

How to copy (or invoke) non-static method from one class to another

Open dep4 opened this issue 2 months ago • 3 comments

Rafael,

First of all, many thanks for this great framework!

How to copy method2 from ClassB into ClassA (or invoke). For simplicity, it does not access any fields and methods in ClassB.

For Advice it needs to be a static method, which it's not. For MethodCall or MethodDelegation it needs to be a compatible class to be invoked, which it's not. There's an option with ByteCodeAppender, which I could not find a good a example for.

I spent nearly whole day trying to figure it out, if you could show a brief snippet, I appreciate it.

class ClassA {

  void method1() {
  }
}

class ClassB {

  void method2() {
     System.out.println("method2")
  }
}

dep4 avatar Nov 08 '25 17:11 dep4

Thanks! Glad it is useful to you.

You can invoke a MethodCall on a different object, for example via a field. There's no way to copy s method, that's not normally a good idea and brings a lot of caveats.

raphw avatar Nov 08 '25 22:11 raphw

Thanks for the prompt reply! How to invoke method of ClassB on object from ClassA?

Here's an example

public class ClassA {
    public void method1() {
        System.out.println("ClassA.method1");
    }
}

public class ClassB {
    public void method2() {
        System.out.println("ClassB.method2");
    }

    public static void main(String[] args) throws Exception {
        Class<?> dynamicType = new ByteBuddy()
                .subclass(ClassA.class)
                .defineField("targetObject", ClassB.class)
                .method(ElementMatchers.named("method1"))
                .intercept(MethodCall.invoke(ClassB.class.getMethod("method2"))
                        .on(new ClassA()))
                .make()
                .load(ClassB.class.getClassLoader())
                .getLoaded();

        ((ClassA)dynamicType.getDeclaredConstructor().newInstance()).method1();
    }
}

It works when method from ClassB invoked on objectB but not on objectA, shows error Exception in thread "main" java.lang.IllegalStateException: Cannot invoke public void org.example.ClassB.method2() on public static volatile org.example.ClassA org.example.ClassA$ByteBuddy$cvU0S1jP.invocationTarget$dqmt1h1

dep4 avatar Nov 08 '25 23:11 dep4

This will not work as ClassA does not know about ClassB methods.

MethodCall.invoke(ClassB.class.getMethod("method2")).on(new ClassA())

Since you defined a field, maybe you were looking for onField?

raphw avatar Nov 10 '25 23:11 raphw