简体   繁体   English

将Javassist字节码操作与Maven编译集成

[英]Integrating javassist byte code manipulation with maven compilation

I have a maven project which compiles with javac / aspectj compiler. 我有一个用javac / aspectj编译器编译的Maven项目。
I want to run on classes which were compiled a javassist program which manipulate the compiled classes and add stuff to them. 我想在已编译的javassist程序的类上运行,该程序会操纵已编译的类并向其中添加内容。
I thought using the "process-classes" phase to run my tool. 我认为应该使用“过程类”阶段来运行我的工具。
My question is what is the best way to iterate with javassist over the classes files created in the "target/classes" so I can load, fix and save afterwards. 我的问题是,用javassist迭代“目标/类”中创建的类文件的最佳方法是什么,以便以后可以加载,修复和保存。
Another requirement is to run the tool on test classes as well. 另一个要求是也要在测试类上运行该工具。
If there is an open source project which does similar stuff it will be great to see a live example. 如果有一个开源项目做类似的事情,那么看到一个实时示例将是很棒的。
Thanks, 谢谢,
Avner 阿夫纳

I stumbled upon the same problem recently and I wrote a small Maven Plugin to apply Javassist class transformations during build time. 最近,我偶然发现了一个相同的问题,并且编写了一个小的Maven插件来在构建期间应用Javassist类转换。 I've shared the code on https://github.com/drochetti/javassist-maven-plugin 我已经在https://github.com/drochetti/javassist-maven-plugin上共享了代码

You've guessed right, you should use the process-classes phase and the tricky part is the classpath setup. 您已经猜对了,应该使用流程类阶段,而棘手的部分是类路径设置。 After some trials and errors I've managed to guess the whole ClassPath problem among Project, Dependencies and Javassist (please, refer to com.github.drochetti.javassist.maven.JavassistMojo.execute() code if you want to check the solution). 经过一些试验和错误,我设法猜测了Project,Dependencies和Javassist之间的整个ClassPath问题com.github.drochetti.javassist.maven.JavassistMojo.execute()如果要检查解决方案,请参阅com.github.drochetti.javassist.maven.JavassistMojo.execute()代码) 。

There're some guidelines on GitHub link above, but basically you need to: 上面的GitHub链接上有一些准则,但是基本上您需要:

1 - Configure the plugin on your pom.xml 1-在pom.xml上配置插件

<plugin>
    <groupId>com.github.drochetti</groupId>
    <artifactId>javassist-maven-plugin</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <configuration>
        <includeTestClasses>false</includeTestClasses>
        <transformerClasses>
            <transformerClass>com.domain.ToStringTransformer</transformerClass>
        </transformerClasses>
    </configuration>
    <executions>
        <execution>
            <phase>process-classes</phase>
            <goals>
                <goal>javassist</goal>
            </goals>
        </execution>
    </executions>
</plugin>

2 - Implement a ClassTransformer , here's an example: 2-实现ClassTransformer ,这是一个示例:

/**
 * Silly transformer, used to hack the toString method.
 */
public class ToStringTransformer extends ClassTransformer {

    /**
     * We'll only transform subtypes of MyInterface.
     */
    @Override
    protected boolean filter(CtClass candidateClass) throws Exception {
        CtClass myInterface = ClassPool.getDefault().get(MyInterface.class.getName());
        return !candidateClass.equals(myInterface) && candidateClass.subtypeOf(myInterface);
    }

    /**
     * Hack the toString() method.
     */
    @Override
    protected void applyTransformations(CtClass classToTransform) throws Exception {
        // Actually you must test if it exists, but it's just an example...
        CtMethod toStringMethod = classToTransform.getDeclaredMethod("toString");
        classToTransform.removeMethod(toStringMethod);

        CtMethod hackedToStringMethod = CtNewMethod.make(
                "public String toString() { return \"toString() hacked by Javassist\"; }",
                classToTransform);
        classToTransform.addMethod(hackedToStringMethod);
    }

}

Note: to implement a transformer you'll need to add the plugin as a dependency of your project, but don't worry as it's only used during build time it can be provided scoped, this way it'll not be a dependency of your final build. 注意:要实现转换器,您需要将插件添加为项目的依赖项,但是不用担心,因为它仅在构建时使用,可以提供作用域,这样就不会成为您的依赖项。最终版本。

I hope that helps! 希望对您有所帮助! Let me know if you need further help. 让我知道您是否需要进一步的帮助。

Daniel 丹尼尔

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM