簡體   English   中英

Class 用Bytebuddy代理重新改造

[英]Class Retransformation with Bytebuddy Agent

我正在使用 ByteBuddy API 編寫一個 Java 代理。因此,我想了解使用 Bytebuddy DSL 的重新轉換功能已經加載的類的方法委托。 當我使用-javaagent參數啟動應用程序時,一切正常,控制台 output 被更改,但是在運行時附加 java 代理時,執行 agentmain 方法,但控制台 output 沒有更改。 也許我缺少一些進一步的 ByteBuddy 配置。 任何幫助將不勝感激!

這是代理代碼:

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! ");
  }
}

這是應用程序代碼:

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);
    }
  }
}

這是附加代理的代碼:

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

您可能需要添加.disableClassFormatChanges()因為大多數 JVM 不支持在重新轉換時更改類的形狀。

另外,考慮注冊一個AgentBuilder.Listener看看為什么不能轉換 class。 儀器 API 會抑制所有其他錯誤。

通常情況下,在重新轉換時, Advice API 更適合轉換。 它支持委托 API 的大部分功能,但工作方式略有不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM