为了账号安全,请及时绑定邮箱和手机立即绑定

无法使用 ByteBuddy Agent 转换类

无法使用 ByteBuddy Agent 转换类

富国沪深 2023-06-14 16:15:29
我实际上正在用 ByteBuddy API 编写一个 Java 代理,我需要在其中监视一些方法。比方说我需要记录一个方法的执行时间。这是我的代码:    public class PerfAgents {     public static void premain(String agentArgs, Instrumentation inst){        LOGGER.info("[Agent] Loading classes ...");        Class classToMonitor = getClassFromArgs(agentArgs);        String methodToMonitor = getMethodFromArgs(agentArgs);        installAgent(inst, classToMonitor, methodToMonitor);    }     private static void installAgent(Instrumentation instrumentation, Class<?> classToMonitor, String methodToMonitor) {      new AgentBuilder.Default()           .type(is(classToMonitor))           .transform((builder, typeDescription, classLoader, module) ->                {                    LOGGER.info("Transforming {} for {}", method, classToMonitor.getSimpleName());                    return builder.method(named(methodToMonitor))                           .intercept(MethodDelegation.to(TimerInterceptor.class));           }).installOn(instrumentation);  }}这TimerInterceptor类似于LoggerInterceptor我在 ByteBuddy 教程中找到的,我在其中使用了@SuperCall注释。问题不是我不确定 ByteBuddy 是否将转换应用于提供的类和方法。我可以看到代理正在我的应用程序中加载,但是当我执行我的监控方法时,没有任何反应。这是我的 TimerInterceptor 类:static class TimerInterceptor {    private static Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class);    public static Object log(@SuperCall Callable<Object> callable) throws Exception {        LocalTime start = LocalTime.now();        Object called = callable.call();        LocalTime end = LocalTime.now();        Duration between = Duration.between(start, end);        LOGGER.info("Execution time : {} ms", between.toMillis());        return called;    }}任何帮助,将不胜感激。
查看完整描述

1 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

您没有将 Byte Buddy 配置为重新转换已加载的类。.with(RetransformationStrategy.RETRANSFORM)您可以通过在代理构建器 DSL 中进行设置来实现。

如果您可以避免重新转换,即如果您只检测在执行代理时未加载的应用程序类,则可以跳过此步骤。相反,使用基于字符串的匹配器并且不加载该类。如果需要更丰富的描述,也可以使用aTypePool.Default让字节好友在不加载类的情况下解析类文件。

要查看 Byte Buddy 在做什么,您可以注册一个Listener.StreamWriting.toSystemOut()所有发现的类都打印到控制台的位置,包括任何潜在的错误。


查看完整回答
反对 回复 2023-06-14
  • 1 回答
  • 0 关注
  • 160 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信