在 Java 代理工具中替换/交换 Java class

Replacing / Swapping a Java class in Java agent instrumentation

我读过这个 post which does the bytecode instrumentation in a "line by line" approach. It's clumsy and bug-prone. I wonder if Javassit supports "replacing" or "swapping" a class with an instrumented class. I see the redefineClasses 方法,但我不确定它是否用于此目的,而且我找不到任何相关示例。

如果 SO 中的任何人都可以给我一个在 Javassist

中使用 redefineClasses 的示例,我将不胜感激

我的目标是使用 Java 工具在多个 Java classes 和方法中提取一些有意义的数据,而不仅仅是在这些中打印 start/end 时间例子。这就是为什么我认为“交换 Java class”方法在开发过程中更有效。

你们有什么看法和建议?谢谢。

不提供任何您自己的代码但要求他人提供完整示例代码或其他资源的问题很可能会因为题外话而被关闭。在撰写本文时,您的问题已经吸引了 3 票中的 2 票。请记住我在你的其他问题中告诉你的关于如何提出好的问题以及 MCVE 如何帮助你做到这一点。

因为您是 Java 工具的新手,所以我想详细说明一下 Johannes 的正确评论:我建议您不仅要阅读 Baeldung 文章,还要阅读一些相关的 javadoc。

例如,Java 8 API 文档 Instrumentation.redefineClasses 清楚地说明了重新定义 classes 时的限制:

The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions.

唉,从Java17开始,限制还没有解除,同样的方法在里面介绍如下:

The supported class file changes are described in JVM TI RedefineClasses.

指向的文档与Java 8文档基本相同,只是更详细一些:

The redefinition may change method bodies, the constant pool and attributes (unless explicitly prohibited). The redefinition must not add, remove or rename fields or methods, change the signatures of methods, change modifiers, or change inheritance. The redefinition must not change the NestHost, NestMembers, Record, or PermittedSubclasses attributes. These restrictions may be lifted in future versions.

此外,同样的限制适用于 Instrumentation.retransformClasses,主要区别在于您不是从头开始,而是使用现有的 class 字节作为输入,并且可以按顺序链接多个转换器逐步检测您现有的 class。但即使重新定义,基线仍保持原始 class,如果它之前已加载。