java - 将 javassist 字节码操作与 maven 编译集成

标签 java maven javassist bytecode-manipulation annotation-processing

我有一个使用 javac/aspectj 编译器编译的 maven 项目。
我想在编译的类上运行一个 javassist 程序,该程序操作编译的类并向它们添加内容。
我想使用“进程类”阶段来运行我的工具。
我的问题是用 javassist 迭代在“目标/类”中创建的类文件的最佳方法是什么,这样我就可以在之后加载、修复和保存。
另一个要求是也在测试类上运行该工具。
如果有一个开源项目可以做类似的事情,那么看到一个真实的例子会很棒。
谢谢,
艾夫纳

最佳答案

我最近偶然发现了同样的问题,我写了一个小的 Maven 插件来在构建期间应用 Javassist 类转换。我在 https://github.com/drochetti/javassist-maven-plugin 上分享了代码

您猜对了,您应该使用process-classes 阶段,棘手的部分是类路径设置。经过一些试验和错误后,我设法猜测了项目、依赖项和 Javassist 之间的整个 ClassPath 问题(请引用 com.github.drochetti.javassist.maven.JavassistMojo.execute() 代码,如果你想检查解决方案)。

上面的 GitHub 链接上有一些指南,但基本上您需要:

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 - 实现一个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);
    }

}

注意:要实现转换器,您需要将插件添加为项目的依赖项,但不要担心,因为它仅在构建期间使用,可以提供范围,这这样它就不会依赖于您的最终构建。

希望对您有所帮助!如果您需要进一步的帮助,请告诉我。

丹尼尔

关于java - 将 javassist 字节码操作与 maven 编译集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12423157/

相关文章:

java - 每当我调用 "InsertionSort"方法时,输出文件都显示为空?我应该在哪里调用这个方法?

java - JSON 响应包含表示为小数的字符

linux - Maven enforcer 插件 1.4.1 或其依赖项之一无法解析

java - 使用 javassist 创建非静态初始化程序

java - 更改已编译类中的所有类引用

java - 无法通过 JDBC 禁用 Oracle 外键

java - 可滚动分页客户端-服务器

java - 处理程序调度失败;嵌套异常是 java.lang.AbstractMethodError : javax. xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V

java - 构建Maven项目: Giving compilation Error

javassist异常