byte-buddy
byte-buddy copied to clipboard
Wrapper around method code
I have a method like:
public void checkName(String name) {
//Some code here
}
I would like to instrument this as under:
File file = Utils.getTempFile();
try (FileWriter fw = new FileWriter(file)) {
fw.write(new Date().toString());
// Call original code of checkName <----
}
I tried
@RuntimeType
public static void intercept(@Origin Method m, @SuperCall Callable<?> zuper) throws Exception {
File file = Utils.getTempFile();
try (FileWriter fw = new FileWriter(file)){
fw.write(new Date().toString());
zuper.call();
}
}
But that gave me an error that
None of [public static void test.MethodWrapper.intercept(java.lang.reflect.Method,java.util.concurrent.Callable) throws java.lang.Exception]
allows for delegation from public void MyClass.checkName(java.lang.String)
How do I achieve this ?
Do you rebase? With a redefinition, static methods do not have a super method and the delegator could not be bound.
I will have to confess that I dont understand those details. I am totally new to ByteBuddy and trying to understand the terms. If you have a suggestion as to how to achieve a wrapper around my method code that use a try-with-resources, I am willing to try any option
Can you show how your Byte Buddy code looks like? How do you apply the delegation?
I tweaked the code a bit but still getting the same issue. It seems it looks for @OnMethodEnter and @OnMethodExit annotations in the Advice class. Here is the code I am using:
AgentBuilder.Transformer transformer =
new AgentBuilder.Transformer() {
@Override
public Builder<?> transform(
Builder<?> builder,
TypeDescription typeDescription,
ClassLoader classLoader,
JavaModule module,
ProtectionDomain protectionDomain) {
return builder
.method(ElementMatchers.named("invoke"))
.intercept(Advice.to(MethodProfiler.class));
}
};
AgentBuilder builder =
new AgentBuilder.Default()
.with(RedefinitionStrategy.RETRANSFORMATION)
.disableClassFormatChanges();
Narrowable narrowable = builder.type(ElementMatchers.nameEndsWith("InvokeManager"));
Extendable extendable = narrowable.transform(transformer);
ResettableClassFileTransformer resettableClassFileTransformer =
extendable.installOn(instrumentation);
The code for MethodProfiler class is :
public class MethodProfiler {
public static void intercept(@SuperCall Callable<?> zuper) {
try {
File file = File.createTempFile("test", "tmp");
try (FileWriter fw = new FileWriter(file)) {
fw.write(new Date().toString());
zuper.call();
}
} catch (Exception e) {
}
}
}
and the signature of the method being instrumented is
public void invoke(Iterable iterable, String st1, String st2);
Since I could not make this work, I decided go with the visitor approach to add onMethodEnter and onMethodExit to fake a wrapper. Would like to take a look at this someday to see what I did wrong, but not needed for now
I am currently rewriting business logic for the static method @onMethodExit through redefine and visitor. The actual test can achieve the effect. But there is also a new problem: there is no problem to run the program directly with idea, but it does not work when packaged into jar. issue1470