How to copy (or invoke) non-static method from one class to another
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")
}
}
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.
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
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?