java - 重新转换 Java Instrumentation Agent 库中的 native 方法

标签 java java-native-interface instrumentation native-methods javaagents

我正在尝试编写一个通过 Attach api 动态加载的 Java 代理库,以重新转换某些方法(出现在某些线程的堆栈跟踪中的方法)以记录方法进入/退出。然后通过自定义 MBean 导出方法入口/导出信息。

只要检测的方法不是 native 的,我当前的“原型(prototype)”到目前为止就可以工作。

根据java.lang.instrument.Instrumentation#setNativeMethodPrefix()的文档,Java 代理应该可以用非 native stub 方法替换 native 方法,并添加另一个名称中带有该前缀的 native 方法,然后将其绑定(bind)到原始 native 方法的 native 代码。

但是,在实现此操作时,我收到此错误:

java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method

这是正确的,因为我添加了新的 native 方法。

仅用非 native 方法替换 native 方法才有效,但随后我无法将调用委托(delegate)回原始 native 方法。在另一个类中定义 native 方法不起作用,因为 native 方法是通过类名和方法名查找的,并且没有 nativeMethodClassSuffix 或类似的内容。在另一个新的类加载器中定义另一个同名的类是可行的,我认为可以通过一些间接方式将调用委托(delegate)给新类,但是一个 native 库只能链接到仅由一个类加载的 native 方法类加载器,因此我无法正确链接 native 方法。

我在这里遗漏了什么明显的东西吗?我的代码有点太长,无法在这里发布,如果有人认为它有帮助,我可以尝试构建一个小型 Java 代理示例来显示问题并在此处链接。

最佳答案

Is there anything obvious I'm missing here? My code is a bit too long to post here, if anyone thinks it helps I can try to build a small example java agent that shows the problem and link to it here.

没有。如果屏蔽掉 native 方法,则不再有任何方法可以从 JNI 调用它。您需要使用 native 代码调用该方法。 (我不知道那是什么,但如果不可能的话我会感到惊讶)

另一个选择是更改对 native 方法的所有引用,而不是将其屏蔽掉。这样,您仍然可以在选择时调用原始方法。

关于java - 重新转换 Java Instrumentation Agent 库中的 native 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13954192/

相关文章:

java - 如何使用 OpenJPA 将对象从一个表 "move"转移到另一个表?

Java Web Start更新文件另一个路径/本地

java - eclipse 中的 JNI :Running the Java code

java - Mac OS X 上的 64 位 libjvm.dylib

c++ - 如何解决 "Didn' t 在路径 : DexPathList in my native callback to Java 上找到类 "..."

android - Android Studio 的 Gradle 测试(检测)

android - 如何在屏幕上产生虚拟触摸?

java - 如何在不重新构建应用程序的情况下重新部署到tomcat

java - 在java中搜索 vector

android - 如何在 Android Instrumentation 测试中强制改变方向?