Search code examples
javakryo

use the result of function as a new function's parameter, but why exception occurred?


i wrote a lite RPC framework and use kryo serialize object. but exception occurred when i wrote like this

RpcResponse rpcResponse = new RpcResponse(input.readInt(), kryo.readClassAndObject(input), input.readBoolean());

so i use another way to init my RpcResponse object.

int id = input.readInt();
boolean isInvokeSuccess = input.readBoolean();
Object resultOrThrowable = kryo.readClassAndObject(input);

RpcResponse rpcResponse = new RpcResponse(id, resultOrThrowable, isInvokeSuccess);

and it works.

so my question is: is there any difference between these two way that i used?

the exception is

io.netty.handler.codec.DecoderException: com.esotericsoftware.kryo.KryoException: Unable to find class: abc123123
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.esotericsoftware.kryo.KryoException: Unable to find class: abc123123
at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:156)
at com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:133)
at com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:670)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:781)
at org.develcarl.rpc.serializer.RpcResponseSerializer.read(RpcResponseSerializer.java:30)
at org.develcarl.rpc.serializer.RpcResponseSerializer.read(RpcResponseSerializer.java:14)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:790)
at org.develcarl.rpc.serializer.KryoSerializer.deserialize(KryoSerializer.java:56)
at org.develcarl.rpc.netty.NettyKryoDecoder.decode(NettyKryoDecoder.java:28)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:343)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
... 16 more
Caused by: java.lang.ClassNotFoundException: abc123123
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.esotericsoftware.kryo.util.DefaultClassResolver.readName(DefaultClassResolver.java:154)
... 27 more

Solution

  • Yes. The second one works. The order of operations matters, you have int, boolean, Object. In your first example you read int, Object, boolean. You could do,

    int id = input.readInt();
    boolean isInvokeSuccess = input.readBoolean();
    RpcResponse rpcResponse = new RpcResponse(id, 
            kryo.readClassAndObject(input), isInvokeSuccess);
    

    Regardless, you have to read the fields in the order they're written.