【问题标题】:bytecode instrumentation using ClassFileTransformer.transform使用 ClassFileTransformer.transform 的字节码检测
【发布时间】:2009-04-08 10:22:03
【问题描述】:

我用premain 方法编写了一个类,并在该方法中添加了一个ClassFileTransformerInstrumentation (Instrumentation.addTransformer())。

我已经使用

调用了一个应用程序
java -javaagent:<path_to_agnet.jar> <application>

但是ClassFileTransformer.transform() 方法没有被调用。
我观察到正在调用premain
我还观察到,如果我调用Instrumentation.retransformClasses(),则调用ClassFileTransformer.transform()
在第一个定义 (Classloader.defineClass()) 时,transform() 方法未被调用。

有什么线索吗?

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

问候, 雷吉夫。

【问题讨论】:

  • 感谢您的反馈。我刚刚将您的分析添加到我的条目中。您可以选择它作为官方答案,也可以发布您自己的条目并附上一些详细信息,然后选择那个作为官方答案。

标签: java instrumentation


【解决方案1】:

可能的原因

清单不正确

您是否按照all the steps required 定义了 Instrumentation 类?

尤其是“打包”步骤,它涉及在 JAR 清单中指定一组略有不同的属性:

  • 您必须指定一个Premain-Class 属性,而不是Main-Class,该属性给出在您的代理中实现premain() 的类的完整类名。
Premain-Class: my.package.MyAgentClass
  • 如果您的代理使用任何类库,那么您应该指定 Boot-Class-Path 属性,因为您的检测代理需要其库从引导类加载器中可见。
    如果您不这样做,您可能不得不对 JVM 使用古怪的 -Xbootclasspath/a:... 参数。
    命令行参数是让事情顺利进行的一种不错的方式,但从长远来看,您希望使用此属性,因为命令行已经因必须指定 Java 检测代理而增长。还是尽量简单吧。

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

静默异常

Rejeev Divakaran 得到了那个)。

我使用classBeingRedefined.getName() 打印类名。
classBeingRedefined 第一次加载时是null

底线是transform方法中是否存在未捕获的异常
它会被默默地吃掉

【讨论】:

  • 是的,我正在按照上面链接中提到的所有说明进行操作。具体来说(1)在清单中指定了 Premain-Class(还调用了 premain 方法)(2)我的代理非常小,并且与任何其他 jar 没有任何依赖关系(3)Can-Redefine-Classes 和 Can-Retransform-类设置为 true
  • 奇怪。它通常归结为不正确的 MANIFEST 文件,但如果不是这种情况,则需要进行其他测试。你能让文章中的例子工作(分析变压器)吗?这将表明问题出在您的代码中还是在您的 JDK/JRE 配置中。
  • 知道了!我正在使用 classBeingRedefined.getName() 来打印类名。第一次加载时,classBeingRedefined 为 null。底线是变换方法中是否存在未捕获的异常。它会被默默地吃掉。感谢您的所有帮助。
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-05
  • 2015-03-18
相关资源
最近更新 更多