Search code examples
byte-buddy

From a ByteBuddy-generated method, how do I set a (public) instance field in an object received as an argument to the return value of a MethodCall?


I am generating a class in ByteBuddy.

As part of one method implementation, I would like to set a (let's just say) public instance field in another object to the return value of a MethodCall invocation. (Keeping the example public means that access checks etc. are irrelevant.)

I thought I could use MethodCall#setsField(FieldDescription) to do this.

But from my prior question related to this I learned that MethodCall#setsField(FieldDescription) is intended to work only on fields of the instrumented type, and, looking at it now, I'm not entirely sure why or how I thought it was ever going to work.

So: is there a way for a ByteBuddy-generated method implementation to set an instance field of another object to the return value of a method invocation?

If it matters, the "instrumented method" (in ByteBuddy's terminology) accepts the object whose field I want to set as an argument. Naïvely I'd expect to be able to do something like:

MethodCall.invoke(someMethod).setsField(somePublicField).onArgument(2);

There may be problems here that I am not seeing but I was slightly surprised not to see this DSL option. (It may not exist for perfectly good reasons; I just don't know what they would be.)


Solution

  • This is not possible as of Byte Buddy 1.10.18, the mechanism was originally created to support getters/setters when defining beans, for example. That said, it would not be difficult to add; I think it would even be easiest to allow any custom byte code to be dispatched as a consumer of the method call.

    I will look into how this can be done, but as a new feature, this will take some time before I find the empty space to do so. The change is tracked on GitHub.