2

Byte Buddy 0.7.7 から 1.0.2 に移行する際に、テスト スイートでいくつかの問題が発生しています。

簡単な例を次に示します。

public class ReproBug {

    @Test
    public void test() {
        ByteBuddyAgent.install();

        new AgentBuilder.Default().type(nameStartsWith("test"))
                .transform(new AgentBuilder.Transformer() {

                    @Override
                    public Builder<?> transform(Builder<?> builder, TypeDescription typeDescription) {

                        return builder.method(isDeclaredBy(typeDescription)).intercept(to(new Object() {

                            @RuntimeType
                            public void intercept(@SuperCall Callable<?> zuper, @Origin Method method) {
                                System.out.println("intercepting " + method.getName());
                            }
                        }));
                    }
                }).installOnByteBuddyAgent();

        MyClass.staticMethod();
    }
}

のコードMyClass:

class MyClass {
    public static void staticMethod() {
        System.out.println("in staticMethod");
    }
}

Byte Buddy 0.7.7 ではエラーは報告されませんが、1.0.2 では のようなエラーが発生しCannot resolve type description for test.MyClass$auxiliary$dUGbkatoます。

完全なログ (AgentBuilder.Listener から): http://pastebin.com/ytsQR5bi

メソッドが傍受されることに注意してください。

callただし、一部のテストでは、補助クラスのメソッドをインターセプトするため、インターセプトの量が 2 倍になります。

4

1 に答える 1

1

リスナーを追加すると、問題を再現できました。0.7.7 と 1.0.3 の違いは、Byte Buddy が補助クラスをロードする時間です。1.0.3 では、Byte Buddy はクラスの静的初期化子の一部としてクラスをロードします。このようにして、Byte Buddy は、補助クラスがインストルメント化されたクラスの早期ロードをトリガーしないようにします。たとえば、補助クラスがインストルメント化されたクラスのサブタイプである場合などです。以前は、これによりインストルメンテーションが中止され、Byte Buddy はエラーで失敗していました。

つまり、補助クラスはインストルメンテーション プロシージャの一部としてロードされなくなり、トランスフォーマーがアクティブになるようにエージェント API にクラス ロード イベントを発行します。マッチャーにはテスト付きのすべての型が含まれており、補助型は計測された型と同じパッケージにあるため、 はこれらの補助型を計測しようとしましたが、クラス ファイルを見つけることができませんでした。したがって、例外が発生しました。

Byte Buddy 1.1.0 (リリース予定) では、ビルダー API に新しいメソッドがあり、ignoreTypes完全に無視する必要がある任意の型を指定できます。デフォルトでは、Byte Buddy は合成タイプを無視するようになりました。補助タイプは合成であるため、発生する問題はデフォルトのセットアップでは発生しなくなりました。

ただし、実際には、ログ内の情報がプログラムに影響を与えることはありません。元のタイプは、想定どおりに常にインストルメント化されます。問題が発生するのは、Byte Buddy が、重複したインストルメンテーションが発生している補助型を実際にインストルメント化できる場合のみです。

一般的な注意点として、単体テストでは、エージェントを登録した後は必ずトランスフォーマーを削除する必要があります。次に例を示します。

Instrumentation inst = ByteBuddyAgent.install();
ClassFileTransformer cft = agentBuilder.installOnByteBuddyAgent();
try {
 // run test
finally {
  inst.removeTransformer(cft);
}

クラスの完全修飾名を指定するなどして、インターセプトするクラスのテストを非常に具体的にすることもお勧めします。

于 2016-01-22T12:31:51.520 に答える