Javaagent。做什么的?

时间:2013-09-23 14:43:10

标签: java bytecode javaagents

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

据我所知,Java中没有标准的方法来处理字节码,无论如何你都不得不求助于库。

因此,在调用defineClass()之前,我尝试在自己的自定义类加载器中使用这些库。而且,当然,它运作得非常好。我可以用相同的方式更改字节码,就像我使用ClassFileTransformer的{​​{1}}方法一样。

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

顺便提一下,关于仪器和类加载器之间差异的问题。自定义类加载器不能更改通过引导类加载器加载的类,如java.lang.Object(尽管在执行此操作之前应该三思而后行)。此外,您的自定义类加载器必须实现原始的类加载器语义才能工作。否则,例如,如果您尝试使用委托拦截加载,则类加载器将错过JVM尝试解析依赖项时加载的所有类。由应用程序(例如,由RMI)创建的另一个ClassLoader加载的所有类都不会被您的自定义类加载器处理。

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