接口实现错误
Error in implementation with interface
抱歉我的英语不好,我在实现时遇到了问题。
我有一个抽象 class 只有一个实现接口的方法
package br.com.teste;
public abstract class Test implements IDefault
{
@Override
public String test1()
{
return "Test method Class";
}
}
我有一个抽象class方法的接口
package br.com.teste;
public interface IDefault
{
public String test1();
}
我还有第二个接口,它扩展到第一个接口,还有一个方法
package br.com.teste;
public interface ITest extends IDefault
{
public String test2();
}
拦截器
package br.com.teste.intercept;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import net.bytebuddy.dynamic.TargetType;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.Super;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
public class ProxyInvocationHandler
{
@RuntimeType
public static Object intercept(@SuperCall Callable<?> callable, @Super(proxyType = TargetType.class) Object delegate, @Origin Class<?> clazz, @Origin Method method, @AllArguments Object[] args) throws Exception
{
System.out.println(method.getName());
//
return null;
}
}
我使用的代码
package br.com.teste;
import br.com.teste.intercept.ProxyInvocationHandler;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
public class Main
{
@SuppressWarnings("unchecked")
public static void main(String... args)
{
try
{
ClassLoader classLoader = Main.class.getClassLoader();
Class<? extends ITest> proxyType = (Class<? extends ITest>) new ByteBuddy(ClassFileVersion.JAVA_V8).subclass(Test.class).implement(ITest.class).method(ElementMatchers.any()).intercept(MethodDelegation.to(ProxyInvocationHandler.class)).make().load(classLoader).getLoaded();
ITest test = proxyType.newInstance();
//
System.out.println(test.test1());
System.out.println(test.test2());
//
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
错误
java.lang.IllegalArgumentException: None of [net.bytebuddy.implementation.bind.annotation.TargetMethodAnnotationDrivenBinder$Record@4d8c5c64] allows for delegation from public abstract java.lang.String br.com.teste.ITest.test2()
at net.bytebuddy.implementation.bind.MethodDelegationBinder$Processor.bind(MethodDelegationBinder.java:827)
at net.bytebuddy.implementation.MethodDelegation$Appender.apply(MethodDelegation.java:1035)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:614)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:603)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:521)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:4102)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1612)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:174)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:155)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2560)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2662)
at br.com.teste.Main.main(Main.java:18)
您的 class Test
仅实现了提供方法 test1
的 IDefault
接口。
它没有实现 ITest
接口,该接口声明方法 test2
。如果它实现了 ITest
接口,则自动意味着它也实现了 IDefault
。
因此,您收到一个异常,提示您创建的 Test
的子 class 中没有方法 test2
可用。
应用正确,byte-ddudy需要使用抽象class中声明的方法。
byte-duddy 界面中的方法创建空白。
由于我正在拦截所有已执行的方法,因此为这些空白生成一个动态 return。
我为此使用了 cglib,它起作用了。
当我从拦截器方法中删除“@SuperCall”参数时,应用程序可以正常工作
@RuntimeType
public static Object intercept(@Origin Method method, @AllArguments Object[] args, @Super Object delegate) throws Exception
{
System.out.println(method.getName());
//
return null;
}
您的 test2
方法在层次结构中是抽象的,它不能通过超级方法调用来调用。因此,@SuperCall
注释不能绑定到 Byte Buddy 拒绝将该方法作为可能的绑定候选者的实例。您可以将 @SuperCall(nullIfImpossible = true)
设置为 null
绑定到该方法,或者添加另一个要求较弱的拦截方法,如果您的方法无法绑定,Byte Buddy 会考虑其第二选择。
抱歉我的英语不好,我在实现时遇到了问题。
我有一个抽象 class 只有一个实现接口的方法
package br.com.teste;
public abstract class Test implements IDefault
{
@Override
public String test1()
{
return "Test method Class";
}
}
我有一个抽象class方法的接口
package br.com.teste;
public interface IDefault
{
public String test1();
}
我还有第二个接口,它扩展到第一个接口,还有一个方法
package br.com.teste;
public interface ITest extends IDefault
{
public String test2();
}
拦截器
package br.com.teste.intercept;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import net.bytebuddy.dynamic.TargetType;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.Super;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
public class ProxyInvocationHandler
{
@RuntimeType
public static Object intercept(@SuperCall Callable<?> callable, @Super(proxyType = TargetType.class) Object delegate, @Origin Class<?> clazz, @Origin Method method, @AllArguments Object[] args) throws Exception
{
System.out.println(method.getName());
//
return null;
}
}
我使用的代码
package br.com.teste;
import br.com.teste.intercept.ProxyInvocationHandler;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
public class Main
{
@SuppressWarnings("unchecked")
public static void main(String... args)
{
try
{
ClassLoader classLoader = Main.class.getClassLoader();
Class<? extends ITest> proxyType = (Class<? extends ITest>) new ByteBuddy(ClassFileVersion.JAVA_V8).subclass(Test.class).implement(ITest.class).method(ElementMatchers.any()).intercept(MethodDelegation.to(ProxyInvocationHandler.class)).make().load(classLoader).getLoaded();
ITest test = proxyType.newInstance();
//
System.out.println(test.test1());
System.out.println(test.test2());
//
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
错误
java.lang.IllegalArgumentException: None of [net.bytebuddy.implementation.bind.annotation.TargetMethodAnnotationDrivenBinder$Record@4d8c5c64] allows for delegation from public abstract java.lang.String br.com.teste.ITest.test2()
at net.bytebuddy.implementation.bind.MethodDelegationBinder$Processor.bind(MethodDelegationBinder.java:827)
at net.bytebuddy.implementation.MethodDelegation$Appender.apply(MethodDelegation.java:1035)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:614)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:603)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:521)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:4102)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1612)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:174)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:155)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2560)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2662)
at br.com.teste.Main.main(Main.java:18)
您的 class Test
仅实现了提供方法 test1
的 IDefault
接口。
它没有实现 ITest
接口,该接口声明方法 test2
。如果它实现了 ITest
接口,则自动意味着它也实现了 IDefault
。
因此,您收到一个异常,提示您创建的 Test
的子 class 中没有方法 test2
可用。
应用正确,byte-ddudy需要使用抽象class中声明的方法。 byte-duddy 界面中的方法创建空白。 由于我正在拦截所有已执行的方法,因此为这些空白生成一个动态 return。 我为此使用了 cglib,它起作用了。
当我从拦截器方法中删除“@SuperCall”参数时,应用程序可以正常工作
@RuntimeType
public static Object intercept(@Origin Method method, @AllArguments Object[] args, @Super Object delegate) throws Exception
{
System.out.println(method.getName());
//
return null;
}
您的 test2
方法在层次结构中是抽象的,它不能通过超级方法调用来调用。因此,@SuperCall
注释不能绑定到 Byte Buddy 拒绝将该方法作为可能的绑定候选者的实例。您可以将 @SuperCall(nullIfImpossible = true)
设置为 null
绑定到该方法,或者添加另一个要求较弱的拦截方法,如果您的方法无法绑定,Byte Buddy 会考虑其第二选择。