gpt4 book ai didi

javaagents:转换顺序

转载 作者:行者123 更新时间:2023-12-04 05:34:54 24 4
gpt4 key购买 nike

在我的项目中,我想分两个阶段转换字节码。顺序很重要。

  • 首先,我需要更改方法定义
  • 然后调用方法的方式

  • 例如
  • String hello() 更改定义至 String hello(String s)
  • Hello.hello() 更改调用至 Hello.hello("newArgument")

  • 我设法添加了变压器,这是第一步。
    public class MyJavaAgent {

    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation inst)
    throws Exception {
    instrumentation = inst;
    instrumentation.addTransformer(new MyClassFileTransformer());
    }
    }

    我的问题是:我可以这样添加新的变压器吗:
    public class MyJavaAgent {

    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation inst)
    throws Exception {
    instrumentation = inst;
    instrumentation.addTransformer(new MyClassFileTransformer());
    instrumentation.addTransformer(new MyClassFileTransformer2());
    }
    }

    并确保 MyClassFileTransformer做他的工作之前 MyClassFileTransformer2 ?

    最佳答案

    有一个简单的方法来测试这个...在每个 Transformer 类的转换方法中添加一条 System.out 指令,该指令将输出相应类的唯一消息。然后检查在控制台上获得输出的顺序。如果您在 Transformer2 之前获得 Transformer1 的唯一消息,那么是的,按顺序调用转换方法。

    这就是我所做的...

    package Test;

    import java.lang.instrument.ClassFileTransformer;
    import java.lang.instrument.IllegalClassFormatException;
    import java.lang.instrument.Instrumentation;
    import java.security.ProtectionDomain;

    public class TransFormerTest {


    public TransFormerTest() {
    super();
    }

    public static void premain(String agentArguments, Instrumentation instrumentation) {
    instrumentation.addTransformer(new Transformer1());
    instrumentation.addTransformer(new Transformer2());
    }
    }

    class Transformer1 implements ClassFileTransformer {
    public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) throws IllegalClassFormatException {
    System.out.println(className + "one"); // one for Transformer
    return bytes;
    }
    }

    class Transformer2 implements ClassFileTransformer {
    public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) throws IllegalClassFormatException {
    System.out.println(className + "two"); // two for Transformer 2
    return bytes;
    }
    }

    所以每次加载一个类并调用转换器时,你应该看到类的名称被打印两次,第一次是 作为后缀,则 两个作为后缀。

    我用一个简单的 Hello World 程序测试了这个理论……这是我的输出:
    Test/Transformer2 - one
    sun/launcher/LauncherHelper - one
    sun/launcher/LauncherHelper - two
    java/lang/Enum - one
    java/lang/Enum - two
    HelloWorld - one
    HelloWorld - two
    java/lang/Void - one
    java/lang/Void - two
    Hello World
    java/lang/Shutdown - one
    java/lang/Shutdown - two
    java/lang/Shutdown$Lock - one
    java/lang/Shutdown$Lock - two

    所以,它似乎确实维持了秩序。

    话虽如此,您是否考虑过链接转换方法?例如...
    public class TransFormerTest  {

    public TransFormerTest() {
    super();
    }

    public static void premain(String agentArguments, Instrumentation instrumentation) {
    instrumentation.addTransformer(new Transformer());
    }
    }

    class Transformer implements ClassFileTransformer {
    public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) throws IllegalClassFormatException {
    byte[] bytes2 = privateTransformer(className, bytes);
    return bytes2;
    }

    private byte[] privateTransformer(String className, byte[] bytes) {
    System.out.println(className + " - one");
    // TODO add code for First Transformation.
    byte[] bytes2 = privateTransformer2(className, bytes);
    return bytes2;
    }

    private byte[] privateTransformer2(String className, byte[] bytes) {
    System.out.println(className + " - two");
    // TODO add code for Second Transformation.
    return bytes;
    }
    }

    这仍然会获得类似的结果,并且这肯定会保持可能发生转换的顺序。

    关于javaagents:转换顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12091283/

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