6

javac/aspectj コンパイラでコンパイルする Maven プロジェクトがあります。
コンパイルされたクラスを操作してそれらに追加するjavassistプログラムをコンパイルしたクラスで実行したい。
「プロセスクラス」フェーズを使用してツールを実行することを考えました。
私の質問は、「ターゲット/クラス」で作成されたクラスファイルをjavassistで反復処理して、後でロード、修正、保存できるようにする最良の方法は何ですか.
もう 1 つの要件は、テスト クラスでもツールを実行することです。
同様のことを行うオープン ソース プロジェクトがある場合は、実際の例を参照してください。
ありがとう、
アヴナー

4

1 に答える 1

9

私は最近同じ問題に出くわし、ビルド時に Javassist クラス変換を適用する小さな Maven プラグインを作成しました。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);
    }

}

注: トランスフォーマーを実装するには、プロジェクトの依存関係としてプラグインを追加する必要がありますが、ビルド時にのみ使用されるため、心配する必要はありませ。最終ビルド。

それが役立つことを願っています!さらにサポートが必要な場合はお知らせください。

ダニエル

于 2012-12-29T02:58:07.460 に答える