netty DefaultChannelPipeline exceptionCaught
The TooLongFrameException
raised by LengthFieldBasedFrameDecoder
means one of the following:
- The remote peer sent a very large message, which exceeds the limit. The default maximum length of a message is 1 MiB. If you expect to receive a message larger than that, specify an alternative maximum length when you construct a
LengthFieldBasedFrameDecoder
. - You passed wrong parameters to
LengthFieldBasedFrameDecoder
so that it is decoding a wrong place in your message. In this case, you'd better re-read the Javadoc ofLengthFieldBasedFrameDecoder
to specify the correct values for you.
Thufir
Updated on June 05, 2022Comments
-
Thufir almost 2 years
Unfortunately, I don't understand this output from the netty server:
BUILD SUCCESSFUL Total time: 3 seconds Jul 27, 2014 2:04:44 AM io.netty.handler.logging.LoggingHandler channelRegistered INFO: [id: 0xcad25a31] REGISTERED Jul 27, 2014 2:04:44 AM io.netty.handler.logging.LoggingHandler bind INFO: [id: 0xcad25a31] BIND(0.0.0.0/0.0.0.0:4454) Jul 27, 2014 2:04:44 AM io.netty.handler.logging.LoggingHandler channelActive INFO: [id: 0xcad25a31, /0:0:0:0:0:0:0:0:4454] ACTIVE Jul 27, 2014 2:04:59 AM io.netty.handler.logging.LoggingHandler logMessage INFO: [id: 0xcad25a31, /0:0:0:0:0:0:0:0:4454] RECEIVED: [id: 0xff40b8a2, /127.0.0.1:37558 => /127.0.0.1:4454] Jul 27, 2014 2:04:59 AM net.bounceme.dur.netty.ServerHandler <init> INFO: starting.. Jul 27, 2014 2:04:59 AM io.netty.channel.DefaultChannelPipeline$TailContext exceptionCaught WARNING: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. io.netty.handler.codec.TooLongFrameException: Adjusted frame length exceeds 1048576: 2901213193 - discarded at io.netty.handler.codec.LengthFieldBasedFrameDecoder.fail(LengthFieldBasedFrameDecoder.java:501) at io.netty.handler.codec.LengthFieldBasedFrameDecoder.failIfNecessary(LengthFieldBasedFrameDecoder.java:477) at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:403) at io.netty.handler.codec.serialization.ObjectDecoder.decode(ObjectDecoder.java:68) at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:343) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:241) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:149) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:125) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116) at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) at java.lang.Thread.run(Thread.java:744) ^Cthufir@dur:~/NetBeansProjects/AgentServer$ thufir@dur:~/NetBeansProjects/AgentServer$
Presumably the netty-based server is complaining that it's receiving bad data in some respect?
client code:
package net.bounceme.dur.client.gui; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.logging.FileHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; import net.bounceme.dur.client.jdbc.Title; public final class ApplicationDriver { private static final Logger log = Logger.getLogger(ApplicationDriver.class.getName()); private TitlesGUI gui = null; private Handler handler = null; public ApplicationDriver() throws IOException, ClassNotFoundException { handler = new FileHandler("application.log"); handler.setFormatter(new SimpleFormatter()); log.setLevel(Level.INFO); log.addHandler(handler); log.info("starting log.."); MyProps p = new MyProps(); String host = p.getHost(); int port = p.getServerPort(); guiThread(); readWrite(host, port); } private void guiThread() { Thread g; g = new Thread() { @Override public void run() { try { gui = new TitlesGUI(); } catch (IOException ex) { log.severe(ex.toString()); } gui.setVisible(true); } }; g.start(); } public static void main(String... args) throws IOException, ClassNotFoundException { new ApplicationDriver(); } private void readWrite(final String host, final int port) throws IOException { Thread inputOutput; final Socket socket = new Socket(host, port); inputOutput = new Thread() { @Override public void run() { while (true) { try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) { gui.setTitle((Title) objectInputStream.readObject()); Thread.sleep(1000); } catch (IOException | ClassNotFoundException | InterruptedException ex) { log.severe(ex.toString()); } } } }; inputOutput.start(); } }
is it a problem that the client is using regular sockets instead of netty? Both on the client and server side POJO's are being sent. (The
Title
class is serializable and the serialVersionUID values match up.)a method from the GUI client (which is a bit large, it's a Netbeans Swing JFrame):
public void setTitle(Title title) { this.title = title; text.setText(title.toString()); }
the point of the above method is for something to send objects to the GUI, which is then updated accordingly. Similarly, I want to fire updates, or other-wise wire the GUI to socket i/o.
I don't really understand the output from the netty server. Is it a problem that the server uses netty while the client uses sockets? Both use the same POJO, with the serialVersionUID value. Here's the netty handler code:
package net.bounceme.dur.netty; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import java.util.logging.Logger; import net.bounceme.dur.jdbc.Title; public class ServerHandler extends SimpleChannelInboundHandler<Title> { private static final Logger log = Logger.getLogger(ServerHandler.class.getName()); public ServerHandler() { log.info("starting.."); } @Override public boolean acceptInboundMessage(Object msg) throws Exception { log.info(msg.toString()); return true; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { log.info(msg.toString()); ctx.write(new Title()); } @Override protected void channelRead0(ChannelHandlerContext chc, Title title) throws Exception { log.info(title.toString()); chc.write(new Title()); } }
Apparently, none of the server handler code is executed, as everything explodes immediately after the client connects.
server code:
package net.bounceme.dur.netty; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.serialization.ClassResolvers; import io.netty.handler.codec.serialization.ObjectDecoder; import io.netty.handler.codec.serialization.ObjectEncoder; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import java.security.cert.CertificateException; import java.util.logging.Logger; import javax.net.ssl.SSLException; public final class Server { private static final Logger log = Logger.getLogger(Server.class.getName()); public static void main(String[] args) throws Exception { MyProps p = new MyProps(); int port = p.getServerPort(); new Server().startServer(port, false); } private void startServer(int port, boolean ssl) throws CertificateException, SSLException, InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast( new ObjectEncoder(), new ObjectDecoder(ClassResolvers.cacheDisabled(null)), new ServerHandler()); } }); b.bind(port).sync().channel().closeFuture().sync(); log.info("connected!"); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
-
Thufir over 9 yearsthanks for the response. I'm going to come back to this. I can send datagrams back and forth ok, so might have to do that? I'd rather use POJO's, of course. I'll probably open a new question later this week. I'll have to do some reading before accepting the answer, but that makes sense. One oddity is these are small POJO's, just String Beans, maybe five fields.
-
Lrrr about 9 yearsThank @trustin "The default maximum length of a message is 1 MiB" really helped:)