byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

How to call method self when use Advice

Open twogoods opened this issue 1 year ago • 4 comments

    @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
    public static boolean enter(@Advice.Origin Method method, 
                                         @Advice.This(typing = Assigner.Typing.DYNAMIC) Object obj) {
               method.invoke();
}

if method is private,you can't use obj.xxx() reflection can do this,decompile source code it looks like A.class.getMethod(xxx).invoke() can has some optimization let code looks like this.xxx()

twogoods avatar Jun 20 '24 03:06 twogoods

You can create a static fake method with the same signature and then use MethodSubstitution to replace the method with the actual one.

raphw avatar Jun 20 '24 11:06 raphw

You can create a static fake method with the same signature and then use MethodSubstitution to replace the method with the actual one.

sample like this? like retry to invoke method,so I want to call method self in Advice api,I prefer Advice api ,dont add new class、method、field In my case method.invoke can translate to this.xxx() in bytecode?or add some @advice.xxx to describe method call to help bytebuddy translate method call to this.xxx()

twogoods avatar Jun 21 '24 03:06 twogoods

And I have another question can Advice api provider @Advice.AllFields struct like map<name,value>

    @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
    public static boolean enter(@Advice.AllArguments(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object[] allArguments){
        method m=findChangeFunctionById();
        allArguments =m.invoke();
}

the code can be a tmp code to change the arguments value,but if I want to change the field I must to write every @Advice.FieldValue(value = "name", readOnly = false)

twogoods avatar Jun 21 '24 03:06 twogoods

You can emulate a self-invocation. As you already discovered you can skip a method using skipOn in enter. You can also repeat a method from an exit advice using repeatOn. The value returned from the (previous call to the) exit advice is then available using @Advice.Exit.

This way, you can first just jump over the method from enter. From exit, you can then simply return from exit to invoke the original code and keep track of your state using @Advice.Exit.

raphw avatar Jun 21 '24 07:06 raphw