Why do I get a WrongMethodTypeException on invokeExact even though MethodHandle is OK

huangapple go评论64阅读模式
英文:

Why do I get a WrongMethodTypeException on invokeExact even though MethodHandle is OK

问题

以下是翻译好的部分:

我正试图调用一个invoke方法,但有一个错误我无法解释。
我听说Invoke Exact方法必须返回,但即使那样也不起作用。

在这段代码中,程序崩溃了。

这是包含我想要调用的方法的类。

s.loadMessageExchanger(new ServerMessageExchanger() {
    @TrafficID(id = "cords")
    public Boolean setCords(ChannelHandlerContext ctx, ByteBuf byteBuf) {
       System.out.println("jaaa");
       return true;
    }
});

以上是您提供的内容的翻译。如果您还有其他疑问或需要进一步的帮助,请随时问我。

英文:

I am trying to call an invoke method and there is an error that I cannot explain.
I have heard that the Invoke Exact method has to return but it did not work even then.

public boolean exec(String id, ChannelHandlerContext ctx, ByteBuf byteBuf) {
        assert ctx != null;
        assert byteBuf != null;

        MethodHandle methodHandle = this.idMethods.get(id);
        if(methodHandle != null) {
            try {
                Object object = this.idObjects.get(id);

                Boolean b = (Boolean) methodHandle.invokeExact(object, ctx, byteBuf);

                return true;
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
        return false;
}

on this code the Programm crash

Boolean b = (Boolean) methodHandle.invokeExact(object, ctx, byteBuf);

java.lang.invoke.WrongMethodTypeException: expected (,ChannelHandlerContext,ByteBuf)boolean but found (Object,ChannelHandlerContext,ByteBuf)Boolean
at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:298)
at java.lang.invoke.Invokers.checkExactType(Invokers.java:309)
at de.moldiy.molnet.MessageExchangerManager.exec(MessageExchangerManager.java:54)
at de.moldiy.molnet.MessageHandler.channelRead0(MessageHandler.java:22)
at de.moldiy.molnet.MessageHandler.channelRead0(MessageHandler.java:7)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:836)

This is the class that contains the method I want to call

s.loadMessageExchanger(new ServerMessageExchanger() {
    @TrafficID(id = "cords")
    public Boolean setCords(ChannelHandlerContext ctx,ByteBuf byteBuf) {
       System.out.println("jaaa");
       return true;
    }
});

答案1

得分: 2

因为您正在调用ServerMessageExchanger实例上的方法,所以您需要将该实例作为第一个参数传递给MethodHandle.invokeExact

类似这样:

ServerMessageExchanger sme;
....
MethodHandle methodHandle = this.methods.get(id);
Boolean b = (Boolean) methodHandle.invokeExact(sme, ctx, byteBuf);
英文:

Since you are invoking a method on an instance of ServerMessageExchanger, you need to pass that instance as the first argument to MethodHandle.invokeExact.

Something like this:

ServerMessageExchanger sme;
....
MethodHandle methodHandle = this.methods.get(id);
Boolean b = (Boolean) methodHandle.invokeExact(sme, ctx, byteBuf);

答案2

得分: 0

我现在知道问题出在哪里了,使用invokeExact时无法定义匿名类,因为类型必须从一开始就知道,所以这是不可能的:

Object object = this.idObjects.get(id);

methodHandle.invokeExact(object, ctx, byteBuf);

但是我可以使用invoke来替代:

Object object = this.idObjects.get(id);

methodHandle.invoke(object, ctx, byteBuf);
英文:

i know now what was wrong, with invokeExact you can't define an anonymous class because the types have to be known from the beginning, so this is not possible:

        Object object = this.idObjects.get(id);

        methodHandle.invokeExact(object, ctx, byteBuf);

But I can just use invoke:

        Object object = this.idObjects.get(id);

        methodHandle.invoke(object, ctx, byteBuf);

huangapple
  • 本文由 发表于 2020年9月29日 18:43:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/64117983.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定