raphw / byte-buddy

Runtime code generation for the Java virtual machine.
https://bytebuddy.net
Apache License 2.0
6.23k stars 804 forks source link

Is `@Advice.SuperCall` supported? How can I call `super.originalMethod()` inside my instrumenting code? #1664

Closed chickenlj closed 6 days ago

raphw commented 3 months ago

In Advice, this is not supported straight forward. The reason is that code is added to the method at the beginning and end, so the original code does no longer exist as an invocation unit. However, you can easily emulate it:

@Advice.OnMethodEnter(skipOn = Advice.NonDefaultValue.class)
static boolean enter() {
  return true;
}

@Advice.OnMethodExit(repeatOn = Advice.NonDefaultValue.class)
static boolean exit() {
  if (Something.invokeRealMethod() {
    return true;
  }
  // ...
  return false;
}

The idea is that you first jump over to exit advice. Then you do your thing and if you want to invoke the original code you "repeat" the method invocation. For this you leave the exit advice and Byte Buddy will jump back to the beginning of the method. You can also use a reference value such as a string, or an integer as a counter. If you then return null or 0 (or false as in the example), you finally leave the original code.