You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm currently porting one of our libraries from CGLib to ByteBuddy and I've encounter a problem with @pipe. I've got a simple proxy that delegates all calls to the wrapped target object. Everything is OK until there is a method returning void on the target object.
My setup is like:
public class X {
public static class WrappedObject {
Object method1() {...}
void method2() {...}
}
public static interface Forwarder<T, S> {
T to(S target);
}
public static class Handler {
protected final WrappedObject wrappedObject;
public Handler(WrappedObject wrappedObject) {
this.wrappedObject = wrappedObject;
}
@RuntimeType
public Object delegate(@Pipe Forwarder<Object, WrappedObject> pipe) {
return pipe.to(wrappedObject);
}
}
public static void main(String... args) throws Exception {
WrappedObject proxiedObject = new ByteBuddy()
.subclass(WrappedObject.class)
.method(any())
.intercept(MethodDelegation.to(new Handler(new WrappedObject())).appendParameterBinder(Pipe.Binder.install(Forwarder.class)))
.make()
.load(X.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded()
.newInstance();
}
}
The proxy cannot be created:
Exception in thread "main" java.lang.IllegalStateException: An illegal stack manipulation must not be applied
at net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation$Illegal.apply(StackManipulation.java:46)
at net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation$Compound.apply(StackManipulation.java:194)
at net.bytebuddy.instrumentation.method.bytecode.bind.annotation.Pipe$Binder$Redirection$MethodCall$Appender.apply(Pipe.java:589)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Entry$Simple.apply(TypeWriter.java:1055)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Engine$ForCreation.create(TypeWriter.java:688)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1143)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:219)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$AbstractDelegatingBuilder.make(DynamicType.java:1611)
at net.bytebuddy.instrumentation.method.bytecode.bind.annotation.Pipe$Binder$Redirection.make(Pipe.java:332)
at net.bytebuddy.instrumentation.Instrumentation$Context$Default.register(Instrumentation.java:808)
at net.bytebuddy.instrumentation.method.bytecode.bind.annotation.Pipe$Binder$Redirection.apply(Pipe.java:342)
at net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder$ParameterBinding$Anonymous.apply(MethodDelegationBinder.java:192)
at net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder$MethodBinding$Builder$Build.apply(MethodDelegationBinder.java:507)
at net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation$Compound.apply(StackManipulation.java:194)
at net.bytebuddy.instrumentation.MethodDelegation$Appender.apply(MethodDelegation.java:998)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Entry$Simple.apply(TypeWriter.java:1055)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Engine$ForCreation.create(TypeWriter.java:688)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1143)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:219)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$AbstractDelegatingBuilder.make(DynamicType.java:1611)
at X.main(X.java:40)
When I change WrappedObject class to:
public static class WrappedObject {
Object method1() {...}
Object method2() {...}
}
it runs fine.
So, is @pipe capable of delegation to void returning methods? Or am I doing something wrong?
The text was updated successfully, but these errors were encountered:
This is indeed a bug, rather a faulty default setup. You can resolve this by setting a different Assigner which knows how to assign a void type to an Object type.
When defining the MethodDelegation, set
new VoidAwareAssigner(new PrimitiveTypeAwareAssigner(ReferenceTypeAwareAssigner.INSTANCE), true)
using the withAssigner method.
This is of course inconvenient and the upcoming version will provide a better solution and you will not longer be required to do so. Thanks for reporting this and for using Byte Buddy.
The bug-fix release 0.4.1 is already available in JCenter and is currently synchronized to Maven Central. It should be available from there in a couple of hours.
I'm currently porting one of our libraries from CGLib to ByteBuddy and I've encounter a problem with @pipe. I've got a simple proxy that delegates all calls to the wrapped target object. Everything is OK until there is a method returning void on the target object.
My setup is like:
The proxy cannot be created:
When I change WrappedObject class to:
it runs fine.
So, is @pipe capable of delegation to void returning methods? Or am I doing something wrong?
The text was updated successfully, but these errors were encountered: