Context
I am implementing byte code transformations with ByteBuddy and the process of manipulation is a multi step process. Because of that, the manipulation has to be able to:
- augment originally existing methods
- create new methods entirely
- augment a method that was introduced via 2.
For 1. I used an @OnMethodExit
advice applied via:
Builder<?> builder = builder.visit(Advice.to(Helper.class)
.on(ElementMatchers.hasMethodNamed(name));
with Helper
the augmentation code for the method (effectively setting a field's value).
When creating new methods, I build them as follows:
Builder<?> builder = builder.defineMethod(…)
.intercept(MethodDelegation.to(OtherHelper.class));
.…;
OtherHelper
consumes the runtime instance via a static method taking @This Object object
as argument.
The problem
In short: I don't see the former transformation applied if it follows the latter. The actual execution order is as follows:
- My type gets processed and a method added via
MethodDelegation.…
. - In a subsequent step I find that newly introduced method and try to augment the implementation generation through
Advice.to(…)
using an@OnMethodExit
advice. - The resulting code has the behavior of step 1 but is lacking the behavior of step 2.
I am assuming I invalidly combine the two parts of the implementation. Any ideas? A hunch: does the ElementMatcher
matching the augmentation by name not see the method introduced using ….defineMethod(…)
yet? The name
is coming from some method inspection I start from builder.toTypeDescription()
which actually makes me assume that the to-be-created method is already visible to the builder as otherwise it wouldn't be found in that step in the first place.