简体   繁体   中英

Class Retransformation with Bytebuddy Agent

I am writing a Java agent with ByteBuddy API. Therefore, I want to get in touch with the method delegation of classes that are alredy loaded using the retransformation capabilities of the Bytebuddy DSL. When I start the application with the -javaagent parameter everything works fine and the console output gets changed but when attaching the java agent at runtime the agentmain method is executed but the console output does not get changed. Maybe im missing some further ByteBuddy configuration. Any help would be appreciate!

Here is the agent code:

public class AgentMain {
  private static final String CLASS = "testing.Test";
  private static final String METHOD = "doSomething";

  public static void premain(String agentArgs, Instrumentation instrumentation) {
    System.out.println("premain...");
    new AgentBuilder.Default()
      .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
      .type(ElementMatchers.named(INSTRUMENTED_CLASS))
      .transform(new AgentBuilder.Transformer() {
        @Override
        public DynamicType.Builder transform(
          DynamicType.Builder builder,
          TypeDescription typeDescription,
          ClassLoader classLoader,
          JavaModule javaModule
        )
        {
          return builder.method(named(INTERCEPTED_METHOD))
            .intercept(MethodDelegation.to(Interceptor.class));
        }
      }).installOn(instrumentation);
  }

  public static void agentmain(String agentArgs, Instrumentation instrumentation) {
    System.out.println("Running agentmain...");
    new AgentBuilder.Default()
      .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
      .type(ElementMatchers.named(INSTRUMENTED_CLASS))
      .transform(new AgentBuilder.Transformer() {
        @Override
        public DynamicType.Builder transform(
          DynamicType.Builder builder,
          TypeDescription typeDescription,
          ClassLoader classLoader,
          JavaModule javaModule
        )
        {
          return builder.method(named(INTERCEPTED_METHOD))
            .intercept(MethodDelegation.to(Interceptor.class));
        }
      }).installOn(instrumentation);
  }
}
public class Interceptor {
  public static void doSomething(String string) throws Exception {
    System.out.println("Intercepted! ");
  }
}

Here is the application code:

public class Main {
  public static void main(String args[]) throws Exception {
    while (true) {
      Thread.sleep(1000);
      String say = "Not intercepted!";
      Test test = new Test();
      test.doSomething(say);
    }
  }
}

Here is the code to attach the agent:

public class Attacher {
  public static void attach(String jarFile, String pid) {
    try {
      ByteBuddyAgent.attach(new File(jarFile), pid);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
}

You probably need to add .disableClassFormatChanges() as most JVMs do not support changing the shape of classes upon a retransformation.

Also, consider registering an AgentBuilder.Listener to see why a class cannot be transformed. The instrumentation API suppresses all errors otherwise.

Normally, when retransforming, the Advice API is better suited for transformation. It supports most features of the delegation API but works slightly different.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM