2017-06-13 23 views
0

Java Agent提供了测试Java编程语言代码所需的服务。 ClassFileTransformer是Java代理的实现,转换发生在JVM定义的类之前。唯一的方法transform需要实现,并且每个新的类定义都会调用它。如何Java Agent作品的说明:如何通过Java代理保存检测到的java字节码?

Java Agent

我想保存改动的代码,这样我就可以不插装,每次运行仪表类文件。正如我检查Interface Instrumentation,我没有看到任何直接的API来保存转换后的字节码。我想知道是否可以使用Java Agent来实现我的目标或其他工具?

+0

你正在仪表自己的班级或第三方图书馆? – vempo

+0

@vempo我自己的类,示例代码与可用的源代码。 – Qoros

回答

1

您需要的是构建时或编译时仪器,而不是运行时。大多数字节码检测工具都支持 - Javassist,AspectJ,ASM

实际上,您可以将由您的代理程序检测的字节码保存到.class文件,其结果只是表示类的字节数组。但是,您必须至少与代理程序一起运行您的程序,并确保您加载了所有需要仪器的类,以便为每个类创建一个.class文件。所以我不推荐这种方法

if (shouldInstrument) { 

    CtClass cclass = pool.get(className.replaceAll("/", ".")); 

    // Instrument the class here 

    byte[] bytecode = cclass.toBytecode(); 

    File outputFile = new File(String.format("%s/%s.class", outputDirectory, className)); 
    Files.createDirectories(outputFile.getParentFile().toPath()); 

    try (FileOutputStream fos = new FileOutputStream(outputFile)) { 
     fos.write(bytecode); 
    } 

    return bytecode; 
} 

另外,如果你的目标是不污染的源代码与样板代码一些功能添加到您自己的类,你可以操纵的源代码,而不是字节码。源 - >生成源 - >字节码(编译)。例如,使用注释和自定义annotation processor

+0

谢谢。您提到将您的代理所检测的字节码保存到'.class'文件中。我尝试过,但是我发现每个班级都会调用'transform'函数。我也尝试将所有转换后的代码保存到一个类中,但它不起作用。 – Qoros

+0

我的意思是你可以只用你需要的类并将它们保存在相应的类文件中。 – vempo

+0

“最外层”是什么意思?你在谈论内部类吗?我认为你在这里处理不正确的假设。在单个Java源文件中声明的所有类仍然具有各自的.class文件。 transform()方法不是应用于Java源文件,而是应用于每个单独的类 - 一次加载一个类。尝试运行我的代码和内部类,你会看到类似Test $ 1.class(匿名),Test $ Inner.class,Test $ Inner $ Deeper.class等 – vempo