【问题标题】:Error in implementation with interface接口实现错误
【发布时间】:2017-01-29 14:59:29
【问题描述】:

很抱歉我的英语不好,我在执行时遇到了问题。

我有一个抽象类,只有一个实现接口的方法

    package br.com.teste;

public abstract class Test implements IDefault
{
    @Override
    public String test1()
    {
        return "Test method 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)

【问题讨论】:

  • 不应该Test实现ITest吗?错误听起来像 bytebuddy 没有找到在您的实例上调用该方法的方法,如果它没有实现正确的接口,肯定会出现这种情况。
  • 我同意 BeyelerStudios。您的类 Test 实现 IDefault 而不是 ITest。因此,您只能访问您的方法 test1()。

标签: java byte-buddy


【解决方案1】:

您的test2 方法在层次结构中是抽象的,不能通过超级方法调用来调用。因此,@SuperCall 注释不能绑定到 Byte Buddy 拒绝该方法作为可能的绑定候选的实例。您可以将@SuperCall(nullIfImpossible = true) 设置为将null 绑定到该方法,或者添加另一个要求较弱的拦截方法,如果您的方法无法绑定,Byte Buddy 会考虑其第二选择。

【讨论】:

    【解决方案2】:

    你的类Test只实现了IDefault接口,它提供了方法test1。 它没有实现ITest 接口,该接口声明了方法test2。如果它实现了ITest 接口,则自动意味着它也实现了IDefault

    因此,您会收到一个异常,指出您创建的 Test 子类中没有可用的方法 test2

    【讨论】:

      【解决方案3】:

      应用正确,byte-ddudy需要使用抽象类中声明的方法。 仅在 byte-duddy 接口中的方法创建为空白。 当我拦截所有执行的方法时,这些空白会生成一个动态返回。 我为此使用了 cglib,它确实有效。

      【讨论】:

        【解决方案4】:

        当我从应用程序的拦截器方法中删除“@SuperCall”参数时

        @RuntimeType
        public static Object intercept(@Origin Method method, @AllArguments Object[] args, @Super Object delegate) throws Exception
        {
            System.out.println(method.getName());
            //
            return null;
        }
        

        【讨论】:

          猜你喜欢
          • 2014-10-10
          • 1970-01-01
          • 2023-03-13
          • 1970-01-01
          • 1970-01-01
          • 2018-01-29
          • 2013-12-27
          • 1970-01-01
          相关资源
          最近更新 更多