有没有办法通过 Advice API 获取方法签名?
Is there a way to get the method signature with Advice API?
我目前正在开发一个 Java 代理,其工作是跟踪(比如说打印)程序中每个线程的当前位置。例如,如果我有一个像这样的 Java 程序:
public class MyClass {
public static void a(String s) {
b(s);
}
public static void b(String s) {
System.out.println(s);
}
public static void main(String[] args) {
a("Hello")
}
}
我希望我的检测程序输出:
[+] Thread X : Entering MyClass.main([])
[+] Thread X : Entering MyClass.a(java.lang.String Hello)
[+] Thread X : Entering MyClass.b(java.lang.String Hello)
[+] Thread X : Entering java.io.PrintStream.println(java.lang.String Hello)
Hello
[-] Thread X : Leaving java.io.PrintStream.println(java.lang.String Hello)
[-] Thread X : Leaving MyClass.b(java.lang.String Hello)
[-] Thread X : Leaving MyClass.a(java.lang.String Hello)
[-] Thread X : Leaving MyClass.main([])
我无法修改原始程序,这就是我创建代理的原因。
我认为 Advice API 是可行的方法,因为它允许我以非常低的计算开销在每个函数的开头和结尾附加代码,但我 运行两个问题:
- 我的主要问题:建议 API 能否检索调用它的方法的签名(Class + 方法)?
- 第二个问题涉及转换每个 class 的每个方法。目前,我的计划是创建一打 AgentBuilder,每个目标函数都有零、一、二、三……参数。有更好的方法吗?参数的类型如何?
目前,我有以下代理人:
public static void agentmain(String agentArgs, Instrumentation inst) {
AgentBuilder mybuilder = new AgentBuilder.Default()
.disableClassFormatChanges()
.with(RedefinitionStrategy.RETRANSFORMATION)
.with(InitializationStrategy.NoOp.INSTANCE)
.with(TypeStrategy.Default.REDEFINE);
mybuilder.type(nameMatches(".*"))
.transform((builder, type, classLoader, module) -> {
try {
return builder
.visit(Advice.to(TraceAdvice.class).on(isMethod()));
} catch (SecurityException e) {
e.printStackTrace();
return null;
}
}).installOn(inst);
}
我的 TraceAdvice class 分别使用 System.out.println("Entering")
和 System.out.println("Exiting")
.
实现 onEnter 和 onExit
提前致谢
您是否尝试过将这些参数添加到您的 before/after 建议方法中?
@Origin Method method,
@AllArguments(readOnly = false, typing = DYNAMIC) Object[] args
打印 Method
对象已经在一个简单的步骤中给出了方法签名。您还可以以任何您认为合适的方式打印 Object[] args
,例如Arrays.toString(args)
甚至 Arrays.deepToString(args)
.
我只是从我的一个建议中复制了片段。如果您不想更改任何参数值,当然您不需要 readOnly = false
.
我目前正在开发一个 Java 代理,其工作是跟踪(比如说打印)程序中每个线程的当前位置。例如,如果我有一个像这样的 Java 程序:
public class MyClass {
public static void a(String s) {
b(s);
}
public static void b(String s) {
System.out.println(s);
}
public static void main(String[] args) {
a("Hello")
}
}
我希望我的检测程序输出:
[+] Thread X : Entering MyClass.main([])
[+] Thread X : Entering MyClass.a(java.lang.String Hello)
[+] Thread X : Entering MyClass.b(java.lang.String Hello)
[+] Thread X : Entering java.io.PrintStream.println(java.lang.String Hello)
Hello
[-] Thread X : Leaving java.io.PrintStream.println(java.lang.String Hello)
[-] Thread X : Leaving MyClass.b(java.lang.String Hello)
[-] Thread X : Leaving MyClass.a(java.lang.String Hello)
[-] Thread X : Leaving MyClass.main([])
我无法修改原始程序,这就是我创建代理的原因。 我认为 Advice API 是可行的方法,因为它允许我以非常低的计算开销在每个函数的开头和结尾附加代码,但我 运行两个问题:
- 我的主要问题:建议 API 能否检索调用它的方法的签名(Class + 方法)?
- 第二个问题涉及转换每个 class 的每个方法。目前,我的计划是创建一打 AgentBuilder,每个目标函数都有零、一、二、三……参数。有更好的方法吗?参数的类型如何?
目前,我有以下代理人:
public static void agentmain(String agentArgs, Instrumentation inst) {
AgentBuilder mybuilder = new AgentBuilder.Default()
.disableClassFormatChanges()
.with(RedefinitionStrategy.RETRANSFORMATION)
.with(InitializationStrategy.NoOp.INSTANCE)
.with(TypeStrategy.Default.REDEFINE);
mybuilder.type(nameMatches(".*"))
.transform((builder, type, classLoader, module) -> {
try {
return builder
.visit(Advice.to(TraceAdvice.class).on(isMethod()));
} catch (SecurityException e) {
e.printStackTrace();
return null;
}
}).installOn(inst);
}
我的 TraceAdvice class 分别使用 System.out.println("Entering")
和 System.out.println("Exiting")
.
提前致谢
您是否尝试过将这些参数添加到您的 before/after 建议方法中?
@Origin Method method,
@AllArguments(readOnly = false, typing = DYNAMIC) Object[] args
打印 Method
对象已经在一个简单的步骤中给出了方法签名。您还可以以任何您认为合适的方式打印 Object[] args
,例如Arrays.toString(args)
甚至 Arrays.deepToString(args)
.
我只是从我的一个建议中复制了片段。如果您不想更改任何参数值,当然您不需要 readOnly = false
.