Search code examples
javabyte-buddy

`Advice.WithCustomMapping` to bind a dynamically added field


Using byte-buddy, I think I need to use Advice.WithCustomMapping to reference arbitrary fields that I choose based on some runtime logic.

However, I am a little lost how to create a reference to fields that I add as part of instrumentation?

AgentBuilder ab = new AgentBuilder.Default();
...
ab = ab.type(named(type))
       .transform((builder, td, _cl, _m) ->
          builder
             .defineField("$lat$", LatencyEvent.class, Visibility.PUBLIC) // new field; I want to create multiple
             .visit(Advice.withCustomMapping()
             .bind(Lat.class, td.getDeclaredFields().filter(named("$lat$")).getOnly()) // ok, here I want to reference the newly added field
             .to(EndLatAdvice.class)
             .on(isMethod().and(named(until)))) // pick a target method
...
private static class EndLatAdvice {
      @Advice.OnMethodEnter
      static void enter(@Lat LatencyEvent l) { // hoping to have access to the newly added field
...
}

Also, while we are at it, I notice for Advice.FieldValue we need to specify readOnly = false, if we mean to write back to that field. How is that done for the WithCustomMapping (assuming that's the right tool for this).


Solution

  • You would supply an instance of Advice.OffsetMapping where you have the instrumented type with all fields supplied as a parameter value.

    From that mapping, you would return an instance of Advice.OffsetMapping.Target.ForField.ReadWrite for this field, unless you have something custom to apply.