我最终使用Byte Buddy编写了一个 Java 代理,它使用 Advice API 在进入和离开方法时打印一条消息。根据我当前的配置,该代理似乎仅适用于由应用程序类加载器加载的类。
但是,我希望它也适用于任何类加载器加载的类。我遇到过多种技术(请参阅enableBootstrapInjection()或ignore()),但它们似乎不起作用。事实上,enableBootstrapInjection()它已经从 ByteBuddy 中消失了,并且该ignore()方法使我的 JVM 恐慌,因为我相信我遇到了循环问题,例如尝试检测该类java.lang.instrument(但这似乎不是唯一的问题,而且我找不到列出这些错误的方法)。
这是我的代理的简化版本:
AgentBuilder mybuilder = new AgentBuilder.Default()
.ignore(nameStartsWith("net.bytebuddy."))
.disableClassFormatChanges()
.with(RedefinitionStrategy.RETRANSFORMATION)
.with(InitializationStrategy.NoOp.INSTANCE)
.with(TypeStrategy.Default.REDEFINE);
mybuilder.type(nameMatches(".*").and(not(nameMatches("^src.Agent")))) // to prevent instrumenting itself
.transform((builder, type, classLoader, module) -> {
try {
return builder
.visit(Advice.to(TraceAdvice.class).on(isMethod()));
} catch (SecurityException e) {
e.printStackTrace();
return null;
}
}
).installOn(inst);
System.out.println("Done");
Run Code Online (Sandbox Code Playgroud)
如有必要,还有我的建议课程的简化版本:
public class TraceAdvice {
@Advice.OnMethodEnter
static void onEnter(
@Origin Method method,
@AllArguments(typing = DYNAMIC) Object[] args …Run Code Online (Sandbox Code Playgroud) 我试图在两个不共享任何 Java 对象的线程之间进行通信(我正在构建一个 Java 代理)。我需要的是以下内容:
Thread agentattachThread = ...;
otherThread.send("Hello");
Run Code Online (Sandbox Code Playgroud)
这将像 Agent Attach 线程中的中断一样处理,如下所示:
public void msgHandler(String msg) {
...
}
Thread.onMessageReceived(msgHandler);
Run Code Online (Sandbox Code Playgroud)
编辑- 考虑到我原来的帖子的答案,我的问题变成:默认情况下 JVM 是否提供一个同步对象,所有线程都可以引用该对象?