Netty ObjectDecoder throws java.io.StreamCorruptedException: unexpected end of block data

I have an unusual problem causing my hair to pull out. I have a Netty Client / Server setup. The server sends a command object to the client. The client then sends each of the binary commands found in the command object to its attached local serial port. The responses to each command (binary string) are stored inside the command object, and when all commands have been executed, the command object is returned to the server. Therefore, I use ObjectEncoder and ObjectDecoder in both my client and server pipelines.

I have one specific repeatable case where the server is throwing "java.io.StreamCorruptedException: unexpected end of block data" (stack trace below) when a specific command object is returned to the server. I am using Netty 3.2.7-Final on server and client, and I am using Oracle Java 1.7.0_02 on both client and server.

What I'm actually doing is that if I run the client and server locally under Windows 7, then the job is done correctly. If I run the server remotely on a Debian Linux system, then a particular job gets done right. However, when I start the server on Linux CentOS 6 system, the work is interrupted every time with an exception. (Client must work in Windows environment)

Any suggestions on how to debug this would be greatly appreciated. I looked into the ObjectEncoder extension so that I can flush the serialized object to disk to see what fits on the wire, but I can't figure out how to get the ChannelBuffer content returned by the encoding method.

java.io.StreamCorruptedException: unexpected end of block data
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1369)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:498)
    at java.lang.Throwable.readObject(Throwable.java:913)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:991)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at java.util.ArrayList.readObject(ArrayList.java:733)
    at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:991)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at org.jboss.netty.handler.codec.serialization.ObjectDecoder.decode(ObjectDecoder.java:129)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:282)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:214)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:351)
    at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:282)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:202)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

      

+1


source to share


1 answer


Since the problem comes with decoding,

You can hex flush the received channel buffer to the log before decoding and analyze it later. You must have your own version of ObjectDecoder like



    @Override
protected Object decode(
        ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {

    ChannelBuffer frame = (ChannelBuffer) super.decode(ctx, channel, buffer);
    if (frame == null) {
        return null;
    }


    logger.debug("Hex dump of object frame [" + ChannelBuffers.hexDump(frame) + "]");

    return new CompactObjectInputStream(
            new ChannelBufferInputStream(frame), classResolver).readObject();
}

      

+1


source







All Articles