问题
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.
回答1:
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")
.
来源:https://stackoverflow.com/questions/47265835/can-i-instrument-outgoing-method-constructor-calls-with-bytebuddy