1

Is Byte Buddy able to Instrumentation#retransformClasses that are already loaded? I want to use Byte Buddy's Java agent feature so that I don't have to specify the -javaagent to be able to instrument classes. This is possible for example with Javassist. But I'm evaluating to replace it with Byte Buddy.

I want to insert a static method call before and after certain methods. If that's possible, an short example would be great!

4

1 に答える 1

3

はい、AgentBuilderAPI を使用して再変換を有効にすることができます。エージェントをインストールすると、Byte Buddy はすでにロードされているすべてのクラスを再変換します。次のように再変換を有効にできます。

AgentBuilder builder = new AgentBuilder.Default()    
  .with(RedefinitionStrategy.RETRANSFORMATION)
  .with(InitializationStrategy.NoOp.INSTANCE)
  .with(TypeStrategy.Default.REDEFINE);

回す必要があるさまざまなスイッチについて疑問に思うかもしれません。

  1. 再定義を有効にする必要があります (インストルメンテーション API に従って、再定義または再変換のいずれか)。

  2. 明示的な初期化戦略を無効にする必要があります。それ以外の場合、Byte Buddy は、生成されたクラスに明示的な初期化子を追加して、クラスがロードされると値を注入しようとします。これにより、HotSpot VM の現在の実装がサポートしていないクラス レイアウトが変更されます。

  3. インストルメンテーション API の制限の 1 つは、前述のとおり、新しいメソッドを追加できないことです。デフォルトでは、Byte Buddy は傍受されたメソッドのコードを、この原則に違反する新しいメソッドにコピーします。de redefinition タイプ戦略を有効にすることで、Byte Buddy がメソッドをリベースしないようにします。

または、Byte Buddy のインターセプト API を使用せずに、インターセプトされたメソッドを完全に置き換えることを選択できますが、最近追加されたAdviceクラスなどを使用して手動で再定義することができます。

Advice.to(Foo.class)このように、メソッドがインターセプトされる前後に、参照されるクラスのバイト コードが挿入される場所など、独自のコードにアドバイスすることで、既存のコードを拡張できます。

class Foo {
  @Advice.OnMethodEnter
  @Advice.OnMethodExit
  private static void intercept() {
    System.out.println("Before/after");
  }
}

詳細については、の javadoc を参照してくださいAdvice

于 2016-03-14T08:57:23.237 に答える