Netty ObjectDecoder генерирует исключение java.io.StreamCorruptedException: неожиданный конец данных блока - PullRequest
1 голос
/ 09 января 2012

У меня необычная проблема, которая заставляет меня рвать на себе волосы.У меня есть настройка Netty Client / Server.Сервер отправляет объект команды клиенту.Затем клиент отправляет каждую из двоичных команд, найденных в объекте команды, на устройство, подключенное к его локальному последовательному порту.Ответы на каждую команду (двоичная строка) хранятся в объекте команды, и когда все команды выполнены, объект команды возвращается на сервер.Поэтому я использую ObjectEncoder и ObjectDecoder в конвейерах клиента и сервера.

У меня есть один конкретный повторяемый случай, когда сервер выдает «java.io.StreamCorruptedException: неожиданный конец данных блока» (трассировка стека)ниже), когда конкретный объект команды возвращается на сервер.Я использую Netty 3.2.7-Final как на сервере, так и на клиенте, и я использую Oracle Java 1.7.0_02 как на клиенте, так и на сервере.

Что меня действительно волнует, так это то, что если я запускаю клиент и сервер локально под Windows 7, то задание выполняется правильно.Если я удаленно запускаю сервер в системе Debian Linux, то конкретное задание выполняется правильно.Однако, когда я запускаю сервер в системе Linux CentOS 6, задание не выполняется каждые раз за исключением.(Клиент должен работать в среде Windows)

Любые предложения относительно того, как отладить это, будут очень приветствоваться.Я посмотрел на расширение ObjectEncoder, чтобы я мог вывести сериализованный объект на диск, чтобы посмотреть, что помещается на провод, но я не могу понять, как получить содержимое ChannelBuffer, возвращаемого методом encode.

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 Ответ

1 голос
/ 09 января 2012

Поскольку проблема возникает при декодировании,

Вы можете произвести шестнадцатеричный дамп полученного буфера канала в журнал перед декодированием и проанализировать его позже.У вас должна быть собственная версия ObjectDecoder, например

    @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();
}
...