【问题标题】:Javaagent. What for?Java代理。做什么的?
【发布时间】:2013-09-23 14:43:10
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: java bytecode javaagents


    【解决方案1】:

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

    【讨论】:

    • 你能举个例子吗?
    • 我很抱歉,但他们在文章中所做的只是使用 ASM 进行字节码转换。类加载器也可以这样做
    • 好的,不同的例子:编写一个分析器,可以计算 java 应用程序加载/使用的类的数量。然后用它来分析,比如说 Apache Tomcat Webserver。你怎么能使用自定义类加载器做到这一点?
    • 我不得不同意你的观点))我不可能只使用我的自定义类加载器来做到这一点
    【解决方案2】:

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

    【讨论】:

    • 这很明智。但据我了解,Mockito 例如使用 javaagent 来操作字节码。 Mockito 将 javaagent 附加到 JVM。但如果这是他们的 javaagent 的唯一目的,他们可以简单地使用他们自己的类加载器。也许我不明白一些东西=)
    • 我认为 Mockito 在运行时动态构建代理,就像 Spring AOP 一样,虽然这只是我的猜测
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-01
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 2016-11-17
      • 2011-01-16
      相关资源
      最近更新 更多