gpt4 book ai didi

java - 字节码操作/增强和 Java Instrumentation API

转载 作者:行者123 更新时间:2023-12-02 09:39:12 25 4
gpt4 key购买 nike

我很难理解字节码操作/增强和 Java Instrumentation API 之间的依赖关系。

根据我对字节码操作/增强的理解,我们有两个选择

  • 构建时 - Java 类被编译为 *.class,然后是其他一些应执行库/应用程序来进行操作。
  • 加载时间 - 仅通过制作使用 Java Instrumentation API,这意味着特定的必须提供javaagent。

我不确定的事情:

  • 是否有诸如构建时字节码操作之类的东西以及支持该操作的框架/库(例如 Javassist、ASM)它们是否使用某种常见方法或只是读取和解析字节码,然后为您提供有办法修改吗?

  • 加载时操作是否仅依赖于 Java Instrumentation API?意味着所有可用的框架/库(例如 Javassist、ASM)都使用 javaagent 来进行操作?

请注意,我对这个主题的经验非常少,因此我可能会误解或错过一些概念。我试图将这个复杂的主题归结为一些简单的解释,即使它非常笼统或使用类比来演示。

最佳答案

将已编译的 Java 类文件视为包含特定 Java 类的任何信息的 byte[] 数组。在这种情况下,检测是指将此字节数组后处理为不同形状的过程,与何时或如何发生无关。可以在编译和类加载之间的任何时间应用检测;在Java中,类甚至可以be instrumented after it has been loaded限制是不改变其形状,即添加/删除字段或方法。但无论何时应用检测,概念都保持不变,即重新排列表示已编译 Java 类的字节数组。

据我所知,任何字节码操作库都允许处理任何来源的类文件。通常,这些库的最通用输入是一个简单的字节数组,为了方便起见,可以选择从类加载器加载它。可以通过 ClassLoader.getResourceAsStream 方法从类加载器中查找类文件,并将类文件的名称作为参数。例如:

classLoader.getResourceAsStream("some/Sample.class")

应该解析一个虚构的some.Sample类的类文件。这通常是因为类加载器需要找到类文件(字节数组),以便在第一次请求时加载该类。

在构建期间,类文件通常位于特定文件夹中,例如在 Maven 构建的 target/classes 文件夹中。要检测这些类,您只需找到这些文件,将它们读入字节数组,然后写回更改的结果。例如,您可以通过编写自己的 Maven 插件来做到这一点,在其中您可以使用 ASM 来调整文件。不过,为了方便起见,您也可以使用更高级的库,例如 Byte Buddy's Maven plugin into which you can load your own plugin并完全避免使用 Maven 插件 API 甚至字节码 API。 (仅供引用,我是 Byte Buddy 的作者。)

在运行时,您可以做非常类似的事情,即找到位于某个文件夹或jar文件中的类文件,找到这些类并在应用程序加载它们之前调整它们。然而,这并不总是有效,因为 jar 文件也可能被其他也会受到影响的应用程序使用。此外,它还要求您的用户从其应用程序中显式激活此检测。因此,类文件检测通常使用 Java 代理来应用,Java 代理可以访问 Instrumentation API,这使得这更加方便。该 API 允许在 Java 的内部类加载机制中安装一个钩子(Hook),这样就可以在加载类之前调整类的字节数组:

instrumentation.addClassFileTransformer(
(Module module, ClassLoader loader, String name,
Class<?> classIfLoaded, ProtectionDomain pd, byte[] classFile) -> {
byte[] transformed = doSomethingWith(classFile);
return transformed;
});

此更改将与应用程序隔离,并且不会更改原始类文件。检测 API 并不意味着使用任何库来修改类文件,这完全取决于您,每个人都在使用某种库,甚至直接操作字节数组。像 Byte Buddy 这样的高级库甚至不需要您实现自己的类文件转换器,而是通过 AgentBuilder API 拥有自己的抽象,但它会在幕后创建一个类文件转换器来使使用检测 API 的独特功能。然而,其他库(例如 ASM 或 Javassist)与 Instrumentation API 没有关系,并且需要您实现自己的类文件转换器,在其中使用这些库的 API 来处理所提供的类文件。

关于java - 字节码操作/增强和 Java Instrumentation API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59512551/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com