PatchExitAdvice

The blueprint whose @OnMethodExit body ByteBuddy copies (inlines) into every exit of an exit-patched method. One blueprint serves all exit patches — the per-patch PatchKey is bound to a constant at weave time, so the inlined call is PatchBridge.fireExit(slot, key, this, args, returned, thrown). Nothing ever calls exit itself — only its body is copied.

Two annotation details are load-bearing, not decoration:

  • onThrowable = Throwable.class — without it the advice runs ONLY on a normal return, and "did this method throw?" is precisely one of the things an exit patch exists to answer. Setting it is also what makes Advice.Thrown legal. ByteBuddy implements it by wrapping the body in a try/catch, which changes the exception table and stack sizes — all inside the Code attribute, so it stays within what disableClassFormatChanges() + retransformation permit.
  • typing = DYNAMIC on Advice.Return — return types vary per method and include primitives and void; only dynamic assignment collapses them all into one Object parameter. Without it ByteBuddy rejects the weave outright.

See also

for the entry phase

Constructors

Link copied to clipboard
private constructor()

Functions

Link copied to clipboard
@Advice.OnMethodExit(onThrowable = Throwable::class)
open fun exit(slot: Int, key: String, @Advice.This(optional = true) self: Any, @Advice.AllArguments args: Array<Any>, @Advice.Return(typing = Assigner.Typing.DYNAMIC) returned: Any, @Advice.Thrown thrown: Throwable)
The inlined @OnMethodExit body: forward the fired patch to fireExit.