Search code examples
javabytecodebyte-buddy

Redefine a specific instance with ByteBuddy


I'm quite new to ByteBuddy and may lack some points here.

I want to redefine a specific instance or more precise, instances of a Type that are instantiated in a specific class with ByteBuddy.

So if I have a class A which declares a variable of Type C and a class B which also declares a variable C, I want just to redefine the instance created in A and leave the original implementation in B. (e.g. just redefine objects which passes an equals check / object == object)

I tried the following, which does not work because the equals check goes against a TypeDescription not against the object in the ElementMatcher.is() method:

Object myObject = new Object();
    new AgentBuilder.Default()
                    .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                    .with(AgentBuilder.Listener.StreamWriting.toSystemError().withTransformationsOnly())
                    .disableClassFormatChanges()
                    .type(ElementMatchers.is(Object.class))
                    .and(ElementMatchers.is(myObject))
                    .transform((builder, typeDescription, classLoader, module) ->
                                       builder.visit(
                                               //Bind all necessary attributes here                                                
                    .installOn(instrumentation);

Is there any way to achieve that? I didn't find anything regarding to ElementMatchers.


Solution

  • You can emulate this as we for example do in Mockito to identify if an instance is a regular instance or a mock when the inline mock maker is used. In general, the instrumentation is implemented to adjust:

    void m() {
      // some code
    }
    

    into

    void m() {
      if (MyFramework.isActive(this)) {
        // your code
      } else {
        // some code
      }
    }
    

    This does however not apply to the matcher, but is something you need to implement in your code. You cannot retransform a class to only adjust for a given set of instances. The idea of a class is to define the shape of any object that is a direct instance of that class.