0

I have a project where I was using Javassist to log outgoing method/constructor calls with code like this:

CtMethod cm = ... ;
cm.instrument(
new ExprEditor() {
    public void edit(MethodCall m)
                  throws CannotCompileException
    {
        if (m.getClassName().equals("Point")
                      && m.getMethodName().equals("move"))
            m.replace("{ $1 = 0; $_ = $proceed($$); }");
    }
});

which assigns '0' to the first argument of the called method and then proceeds with the original call, that is, if cm represents the method someMethod we modify the outgoing calls to Point::move from someMethod:

public int someMethod(int arg1){        
    Point p;
    ...
    Point newPoint =
    //Here we start tampering with the code        
        p.move(0, arg2, arg3, arg4); //Say it was originally p.move(arg1, arg2, arg3, arg4);
    //From here we leave it as it was
    ...
}

I am now trying to migrate to ByteBuddy as I wanted the classes to be compatible with (online) JaCoCo. I've managed to instrument methods and constructors "from the inside" (instrumenting the called methods themselves), but I haven't found any way to do it "from the outside" (instrumenting the calls to such methods from elsewhere). Is there any way to do it with ByteBuddy ?

This question is related to another which asked for a way to catch constructor exceptions as it is the way I achieved it using Javassist.

jmmurillo
  • 173
  • 6

1 Answers1

0

You can change an argument of a method by using Advice which allows you to change an argument prior to the original method's execution:

@Advice.OnMethodEnter
static void enter(@Advice.Argument(value = 0, readOnly = false) int arg) {
  arg = 0;
}

Doing so, the above code will be prepended to the move method that you need to locate using an ElementMatcher like named("move").

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192
  • Instead of the arguments, is there a way to change the body of the method? Specifically, I want to look for a specific library call (like `ArrayList.add()`) being present inside the method and want to add a line of code before it. – itsreddy Mar 06 '20 at 21:55
  • You can replace the method and the substitution API is rather extensible if you want to add your own byte code. A simpler DSL is still in the making. – Rafael Winterhalter Mar 07 '20 at 01:34
  • I have a more detailed query [here](https://stackoverflow.com/questions/60584788/byte-buddy-member-substitution-throwing-illegalstateexception-error). please consider helping me out! – itsreddy Mar 08 '20 at 07:22