Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Byte Buddy access local variable name of a method?

Suppose I have a method m:

public void m() {
  String foo = "foo";
  int bar = 0;
  doSomething(foo, bar);
}

I want to use ByteBuddy to instrument the code so that when calling doSomething in m, it will automatically put the value of foo and bar into a HashMap, pretty much something looks like:

public void m() {
  String foo = "foo";
  int bar = 0;
  context.put("foo", foo); // new code injected 
  context.put("bar", bar); // new code injected
  doSomething(foo, bar);
}

Is there anyway to do this instrumentation via ByteBuddy?

like image 660
Gelin Luo Avatar asked Jan 11 '15 03:01

Gelin Luo


1 Answers

There is built-in way in Byte Buddy to do redefine method m in this way. Byte Buddy is however voluntarily exposing the ASM API on top of which Byte Buddy is implemented. ASM offers quite extensive documentation which would show you how to do this. I can however tell you that it will be quite a lot of code. Note that you require to compile any method with debug symbols enabled, otherwise these internal variables are not available at run time.

Are you however sure you want to do this? Without knowing your exact use case, it feels like it is a bad idea. By implementing this solution, you make the names of local variables a part of your application instead of letting them be an implementation detail.

I would therefore suggest you to rather instrument the doSomething method. Would this suffice yourn what is easily done in Byte Buddy using an interceptor like the following:

class Interceptor {
  void intercept(@Origin Method method, @AllArguments Object[] args) {
    int index = 0;
    for(Parameter p : method.getParameters()) {
      context.add(p.getName(), args[index++]); 
    }
  }
}

This interceptor could then be used as follows:

MethodDelegation.to(new Interceptor()).andThen(SuperMethodCall.INSTANCE);
like image 143
Rafael Winterhalter Avatar answered Nov 06 '22 02:11

Rafael Winterhalter