java - 无法使用 ByteBuddy 代理转换类
问题描述
我实际上正在使用 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;
}
}
任何帮助,将不胜感激。
解决方案
您没有将 Byte Buddy 配置为重新转换已加载的类。您可以通过.with(RetransformationStrategy.RETRANSFORM)
在代理生成器 DSL 中进行设置来实现。
如果您可以避免重新转换,即如果您仅检测执行代理时未加载的应用程序类,则可以跳过此步骤。相反,使用基于字符串的匹配器并且不加载类。如果需要更丰富的描述,也可以使用 aTypePool.Default
让 Byte Buddy 解析类文件而不加载类。
要查看 Byte Buddy 正在做什么,您可以注册一个Listener.StreamWriting.toSystemOut()
所有发现的类都打印到控制台的位置,包括任何潜在的错误。
推荐阅读
- android - Using Android Test Filter (@SmallTest, @MediumTest, @LargeTest) for Local Unit Tests
- android - I try to add firebaseUI but show error Failed to resolve: support-vector-drawable
- php - PHP - Middlewares\FastRoute 包的 nikic/FastRoute 路由
- reactjs - Laravel Mix 和 React 的 NODE_PATH 和绝对导入?
- sql - 如何在 vb.net 中搜索多个字段名称以过滤搜索 datagridview
- cucumber - How to write given, when, then for switching tabs to check login
- angular - Getting undefined error when trying to add array
- php - 将表数据的内容插入/发布到数据库中
- php - 如何用php标签替换方形标签
- php - Dialogflow followup intent detection php sdk