我正在尝试编写一个通过附加 api 动态加载的 Java 代理库,以重新转换一些方法(那些出现在某些线程的堆栈跟踪中的方法)以记录方法的进入/退出。然后通过自定义导出方法进入/退出信息MBean
。
到目前为止,只要检测方法不是本地的,我当前的“原型”就可以工作。
根据java.lang.instrument.Instrumentation#setNativeMethodPrefix()的文档,java 代理应该可以用非本地存根方法替换本地方法,并在其名称中添加另一个带有该前缀的本地方法,然后绑定到原始本机方法的本机代码。
但是,在实施此操作时,我收到此错误:
java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method
这是正确的,因为我添加了新的本机方法。
只有用非本地方法替换本地方法才有效,但是我不能将调用委托回原始本地方法。在另一个类中定义本机方法也不起作用,因为本机方法是通过类名和方法名查找的,没有nativeMethodClassSuffix
或类似的。在另一个新的类加载器中定义另一个同名的类是可行的,我认为可以通过一些间接方式将调用委托给新类,但是一个本机库只能链接到由只有一个类加载的本机方法类加载器,所以我不会正确链接本机方法。
我在这里有什么明显的遗漏吗?我的代码有点长,无法在此处发布,如果有人认为它有帮助,我可以尝试构建一个小型示例 java 代理来显示问题并在此处链接到它。