4

Byte Buddy で動作する簡単な例を取得するのに問題があります。これが私のコードです。

import static java.util.Arrays.asList;
import java.util.stream.Stream;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.MethodDelegation;

public class Foo {
  public static class Bar {
    public void bar (String s, Integer i) {
      System.out.println ("s:" + s + " i:" + i);
    }
  }
  public static class Baz {
    public void baz (Integer i, String s) {
      System.out.println ("i:" + i + " s:" + s);
    }
  }

  public static void main (String[] args) {
    try {
      Class<?> c = new ByteBuddy ()
        .subclass (Object.class)
        .defineMethod ("bar", Void.class, asList (String.class, Integer.class), 1)
        .intercept (MethodDelegation.to (new Bar ()))
        .defineMethod ("baz", Void.class, asList (Integer.class, String.class), 1)
        .intercept (MethodDelegation.to (new Baz ()))
        .make ()
        .load (Foo.class.getClassLoader (), ClassLoadingStrategy.Default.WRAPPER)
        .getLoaded ();
      Stream.of (c.getDeclaredMethods ()).forEach (System.out::println);
    } catch (Exception e) {
      e.printStackTrace ();
    }
  }
}

動作し、尊敬されるインターセプター インスタンスに呼び出しを転送することを期待しますが、次の例外が発生します。

java.lang.IllegalArgumentException: None of [protected void java.lang.Object.finalize() throws java.lang.Throwable, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException, public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll(), public void Foo$Bar.bar(java.lang.String,java.lang.Integer)] allows for delegation from public java.lang.Void net.bytebuddy.renamed.java.lang.Object$ByteBuddy$P87HQ3lQ.bar(java.lang.String,java.lang.Integer)
at net.bytebuddy.implementation.bind.MethodDelegationBinder$Processor.process(MethodDelegationBinder.java:881)
at net.bytebuddy.implementation.MethodDelegation$Appender.apply(MethodDelegation.java:1218)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:510)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:444)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:3193)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1481)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:234)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$AbstractDelegatingBuilder.make(DynamicType.java:2177)
at Foo.main(Foo.java:55)

その例外メッセージの最後にある最も奇妙な部分:

[...] public void Foo$Bar.bar(java.lang.String,java.lang.Integer)] allows for delegation from public java.lang.Void net.bytebuddy.renamed.java.lang.Object$ByteBuddy$P87HQ3lQ.bar(java.lang.String,java.lang.Integer)

私は何を間違っていますか?

4

2 に答える 2

2

あなたはあなたの仮定で正しいです。Byte Buddy はvoid非型を型に割り当てることはできませんVoid。ただし、インターセプターに次のアノテーションを付けた場合、 Byte Buddy はnullvoid メソッドから参照型に割り当てることができます@RuntimeType

public class Bar {
  @RuntimeType
  public void bar (String s, Integer i) {
    System.out.println ("s:" + s + " i:" + i);
  }
}
public class Baz {
  @RuntimeType
  public void baz (Integer i, String s) {
    System.out.println ("i:" + i + " s:" + s);
  }
}
于 2016-01-08T07:54:05.563 に答える
0

私が質問を送信して振り返ったとき、インターセプターの戻り値の型を変更するのではvoidなく、問題は戻り値にある可能性があると思いました。Void

于 2016-01-07T16:16:43.020 に答える