使用ClassFileTransformer.transform的字节码检测

Rej*_*ran 6 java instrumentation

我已经用premain方法编写了一个类,在该方法中我添加了一个ClassFileTransformerto Instrumentation(Instrumentation.addTransformer()).

我已经调用了一个应用程序

java -javaagent:<path_to_agnet.jar> <application>
Run Code Online (Sandbox Code Playgroud)

但是ClassFileTransformer.transform()没有调用方法.
我观察到这premain是被调用的.
我还观察到,如果我打电话Instrumentation.retransformClasses(),那么ClassFileTransformer.transform()就会被调用.
在第一个definition(Classloader.defineClass())上,transform()没有调用方法.

有什么可能是错的线索?

注意:如果有任何帮助,我可以发布源代码.

此致,Rejeev.

Von*_*onC 4

可能的原因

\n\n

\n\n

清单错误

\n\n

您是否遵循了定义 Instrumentation 类所需的所有步骤?

\n\n

特别是“打包”步骤,其中涉及在 JAR\xe2\x80\x99s 清单中指定一组略有不同的属性:

\n\n
\n
    \n
  • Main-Class您必须指定一个属性,该属性给出在代理中Premain-Class实现的类的完整类名,而不是。premain()
  • \n
\n
\n\n
Premain-Class: my.package.MyAgentClass\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n
    \n
  • 如果您的代理使用任何类库,那么您应该指定该Boot-Class-Path属性,因为您的检测代理将需要其库从引导类加载器可见。
    \n 如果您不\xe2\x80\x99 执行此操作,则可能必须-Xbootclasspath/a:...对 JVM 使用古怪的参数。
    \n 命令行参数是让事情顺利进行的一个不错的方法,但从长远来看,您希望使用此属性,因为命令行已经因必须指定 Java 检测代理而不断增长。最好保持尽可能简单。

  • \n
  • 最后,还有Can-Redefine-Classes属性。
    \n 如果它设置为 true,则 Java 检测代理能够重新定义代理本身使用的类。
    \n 这是一个相当奇怪的情况,并且肯定不会\xe2\x80\x99 出现太多。

  • \n
\n
\n\n

\n\n

静默异常

\n\n

Rejeev Divakaran得到了那个)。

\n\n

我用来classBeingRedefined.getName()打印班级名称。
\nclassBeingRedefinednull第一次加载时

\n\n

最重要的是转换方法中是否存在未捕获的异常
\n它会被无声无息地吃掉

\n