使用 ByteBuddy AgentBuilder 添加的建议未被调用
Advice added using ByteBuddy AgentBuilder is not getting invoked
我正在尝试在我的应用程序中添加一个建议,以便在执行流程中调用方法 CassandraFunctions.loadObjectByKey 时调用 onEnter 和 onExit。我使用下面的代码注册了一个建议。
protected void instrument(boolean t) {
Instrumentation instrument = null;
// Get loader initialized in premain class
try {
Class<?> c = Class.forName("my.loader.InstrumentLoader");
java.lang.reflect.Method m = c.getMethod("getInstrument");
instrument = (Instrumentation) m.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
if(instrument == null) {
return;
}
// Add an advice
String clzName = CassandraFunctionsAdvice.class.getName();
new AgentBuilder.Default()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.type(ElementMatchers.named("my.functions.CassandraFunctions"))
.transform(
new AgentBuilder.Transformer.ForAdvice()
.include(Class.class.getClassLoader())
.advice(ElementMatchers.named("loadObjectByKey"), clzName))
.installOn(instrument);
}
建议 class 如下所示:
public class CassandraFunctionsAdvice {
@Advice.OnMethodEnter
public static void onEnter(@Advice.Argument(0) String key) {
String debugText = "OnMethodEnter|loadObjectByKey|key=" + key;
System.out.println(debugText);
}
@Advice.OnMethodExit
public static void onExit(@Advice.Thrown Throwable throwable) {
String debugText = "OnMethodExit|loadObjectByKey";
System.out.println(debugText);
}
}
正在检测的 class 如下所示:
public class CassandraFunctions {
public static Object loadObjectByKey(String key) {
....
return object;
}
}
已检测的 class my.functions.CassandraFunctions 在根据用户请求调用函数 loadObjectByKey 之前加载。我不确定缺少什么以及为什么没有调用建议。
我已经回答了你的问题on the GitHub issue:
建议代码只是一个模板。一旦被 Byte Buddy 内联,私有字段对代码不可见。
您需要问自己的问题是:我可以将这段代码复制粘贴到目标 class 并且它仍然可以编译吗?如果不是,那么你需要改变你的建议。如果你想管理共享状态,你需要将它移动到一个 class ,它可以被相关的 class 加载器访问,并将它注入到一个合适的位置。
我正在尝试在我的应用程序中添加一个建议,以便在执行流程中调用方法 CassandraFunctions.loadObjectByKey 时调用 onEnter 和 onExit。我使用下面的代码注册了一个建议。
protected void instrument(boolean t) {
Instrumentation instrument = null;
// Get loader initialized in premain class
try {
Class<?> c = Class.forName("my.loader.InstrumentLoader");
java.lang.reflect.Method m = c.getMethod("getInstrument");
instrument = (Instrumentation) m.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
if(instrument == null) {
return;
}
// Add an advice
String clzName = CassandraFunctionsAdvice.class.getName();
new AgentBuilder.Default()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.type(ElementMatchers.named("my.functions.CassandraFunctions"))
.transform(
new AgentBuilder.Transformer.ForAdvice()
.include(Class.class.getClassLoader())
.advice(ElementMatchers.named("loadObjectByKey"), clzName))
.installOn(instrument);
}
建议 class 如下所示:
public class CassandraFunctionsAdvice {
@Advice.OnMethodEnter
public static void onEnter(@Advice.Argument(0) String key) {
String debugText = "OnMethodEnter|loadObjectByKey|key=" + key;
System.out.println(debugText);
}
@Advice.OnMethodExit
public static void onExit(@Advice.Thrown Throwable throwable) {
String debugText = "OnMethodExit|loadObjectByKey";
System.out.println(debugText);
}
}
正在检测的 class 如下所示:
public class CassandraFunctions {
public static Object loadObjectByKey(String key) {
....
return object;
}
}
已检测的 class my.functions.CassandraFunctions 在根据用户请求调用函数 loadObjectByKey 之前加载。我不确定缺少什么以及为什么没有调用建议。
我已经回答了你的问题on the GitHub issue:
建议代码只是一个模板。一旦被 Byte Buddy 内联,私有字段对代码不可见。
您需要问自己的问题是:我可以将这段代码复制粘贴到目标 class 并且它仍然可以编译吗?如果不是,那么你需要改变你的建议。如果你想管理共享状态,你需要将它移动到一个 class ,它可以被相关的 class 加载器访问,并将它注入到一个合适的位置。