byte-buddy
byte-buddy copied to clipboard
What are the differences between the three test methods ?
1. It work fine.
@Test
public void test() {
Class<?> clazz = new ByteBuddy()
.subclass(A.class)
.method(not(isDeclaredBy(Object.class)))
.intercept(MethodDelegation.to(new AInterceptor()))
.implement(B.class)
.intercept(FixedValue.value(new A()))
.make()
.load(Thread.currentThread().getContextClassLoader())
.getLoaded();
assertTrue(B.class.isAssignableFrom(clazz));
}
public static class A {
public String sayHello() {
return "Hello";
}
}
public interface B {
A getA();
}
public static class AInterceptor {
@RuntimeType
public Object invoke(@RuntimeType @AllArguments Object[] args,
@Origin Method method,
@SuperCall Callable<Object> callable) throws Exception {
return callable.call();
}
}
2 .it gets wrong.
@Test
public void test() {
Class<?> clazz = new ByteBuddy()
.subclass(A.class)
// change start
.implement(B.class)
.intercept(FixedValue.value(new A()))
.method(not(isDeclaredBy(Object.class)))
.intercept(MethodDelegation.to(new AInterceptor()))
// change end
.make()
.load(Thread.currentThread().getContextClassLoader())
.getLoaded();
assertTrue(B.class.isAssignableFrom(clazz));
}
public static class A {
public String sayHello() {
return "Hello";
}
}
public interface B {
A getA();
}
public static class AInterceptor {
@RuntimeType
public Object invoke(@RuntimeType @AllArguments Object[] args,
@Origin Method method,
@SuperCall Callable<Object> callable) throws Exception {
return callable.call();
}
}
3 . but it works fine.
@Test
public void test() {
Class<?> clazz = new ByteBuddy()
.subclass(A.class)
// change start
.implement(B.class)
.intercept(FixedValue.value(new A()))
.method(not(isDeclaredBy(Object.class)))
.intercept(MethodDelegation.to(new AInterceptor()))
// change end
.make()
.load(Thread.currentThread().getContextClassLoader())
.getLoaded();
assertTrue(B.class.isAssignableFrom(clazz));
}
public static class A {
public String sayHello() {
return "Hello";
}
}
public interface B {
// change method return type
String getA();
}
public static class AInterceptor {
@RuntimeType
public Object invoke(@RuntimeType @AllArguments Object[] args,
@Origin Method method,
@SuperCall Callable<Object> callable) throws Exception {
return callable.call();
}
}
because you are trying to delegatete a method getA
which does not exist in A.class.
Try:
- define a method
getA()
in A.class. - or remove the @SuperCall in AInterceptor.
- or change the method matcher to
.method(not(isDeclaredBy(Object.class)).and(not(isDeclaredBy(B.class))))
- or let the
.implement
call after.method.interceptor
I wonder why it works fine after I change return type in case 2
Byte Buddy does not require target methods to be named equally to a source method.
the method String getA()
can be delegated to AInterceptor.toString()
. You can get an Unloaded
after the make()
method returns, this allows you to step in and call saveIn
to see the generated class information. You can also wait and see what rafael thinks about this issue.
SuperCall
should not work with an abstract method.
Note that the interceptor that you define last will superseed all previous interceptors. So methods not declared by Object will override the previous interface matcher.