2

当我尝试查找使用 Javaagent 的示例时,在大多数情况下,它们都是使用字节码的示例。这些示例使用第三方库,例如 Javaassist。

据我所知,Java 中没有使用字节码的标准方法,无论如何您都必须求助于库。

所以,我尝试在我自己的自定义类加载器中使用这些库,然后再调用defineClass(). 而且,当然,它运行得非常好。我可以用同样的方式改变字节码,就好像我会用ClassFileTransformer'stransform()方法一样。

我是否正确理解 javaagents 的另一个有用特性,而这又是它们的主要特性?因为,首先,javaagent 为您提供了一个Instrumentation对象,而 Java 规范说该instrument包主要用于处理字节码。instrument但是,如果我可以实现我自己的类加载器(在引入包之前我可以做的事情),我为什么需要这样做呢?

4

3 回答 3

4

Instrumentation API 可以在运行时使用,而无需接触代码或编译的字节码。您可以检测每个已编译的 java 程序(即使没有代码)。

于 2013-09-23T14:47:14.270 回答
2

我认为使用 javaagent 是不同的,因为它不是您的应用程序的一部分。您可以编写例如分析代理并将其与任何应用程序一起使用。

于 2013-09-23T14:49:07.270 回答
1

不要混淆 Javaagents 和 Instrumentation。Java 代理可以使用检测,但不是必须的。它可以使用 Java 平台提供的所有其他功能。不使用检测的代理的典型示例是 JMX 代理。看看像JVisualVM提供什么工具。它的大部分功能(分析器除外)都是通过 JMX 代理提供的,而无需使用工具。

顺便说一句,关于您关于仪器和类加载器之间区别的问题。自定义类加载器无法更改通过引导类加载器加载的类java.lang.Object(尽管在这样做之前您应该三思而后行)。此外,您的自定义类加载器必须实现原始类加载器语义才能工作。否则,例如,如果您尝试使用委托来拦截加载,那么当 JVM 尝试解决依赖关系时,您的类加载器将丢失所有加载的类。并且由应用程序(例如由 RMI)创建的另一个类加载的所有类ClassLoader都不会由您的自定义类加载器处理。

因此,Instrumentation 添加了一种独立处理类的方法,并且(可选)甚至允许在加载ClassLoader按需更改它们。

于 2013-09-25T07:48:11.260 回答