I am trying to use ByteBuddy within a Java Agent to instrument some older libraries using OpenTracing. This is associated with the OpenTracing Contrib Java Special Agent project. I had this successfully working when using a private class member to pass the active span, but unfortunately there are instances where this is not feasible (error handling clears out the member field).
So I am trying to use ByteBuddy's ability to create local variables that can be retained from the @Advice.OnMethodEnter to the @Advice.OnMethodExit. This will allow me to create the OpenTracing Span on method enter, and finish it on method exit. I'm not sure my use case is valid, though, since I am using a transformer, which doesn't exactly match the test case for the @Advice.Local annotation.
I tried to follow the syntax used in this test case.
However, the span and scope variables are always null in the exit method. I'm a novice with ByteBuddy, so I'm sure I'm missing something basic.
public class SimpleFrameworkDispatcherAgentRule extends AgentRule {
@Override
public Iterable<? extends AgentBuilder> buildAgent(AgentBuilder agentBuilder) {
return Arrays.asList(agentBuilder
.type(named("org.simpleframework.http.core.Dispatcher"))
.transform((builder, typeDescription, classLoader, module) -> {
return builder.visit(Advice.to(SimpleFrameworkDispatcherAgentRule.class)
.on(named("dispatch")));
}));
}
@Advice.OnMethodEnter
public static void enter(final @Advice.Origin String origin,
final @FieldValue(value = "request", typing = Typing.DYNAMIC) Object request,
final @Advice.Local("span") Object span,
final @Advice.Local("scope") Object scope) {
if (isEnabled(origin)) {
SimpleFrameworkAgentIntercept.enter(request, span, scope);
}
}
@Advice.OnMethodExit
public static void exit(final @Advice.Origin String origin,
final @FieldValue(value = "response", typing = Typing.DYNAMIC) Object response,
final @Advice.Local("span") Object span,
final @Advice.Local("scope") Object scope) {
if (isEnabled(origin)) {
SimpleFrameworkAgentIntercept.exit(response, span, scope);
}
}
}
I instrumented the SimpleFrameworkAgentIntercept enter and exit methods and confirmed that the variables are assigned in enter, but they are null in exit.