diff --git a/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java b/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java index 5def01c0db..08d613e157 100644 --- a/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/ByteToMessageDecoder.java @@ -42,8 +42,29 @@ import java.util.List; * } * * + *
+ * Generally frame detection should be handled earlier in the pipeline by adding a + * {@link DelimiterBasedFrameDecoder}, {@link FixedLengthFrameDecoder}, {@link LengthFieldBasedFrameDecoder}, + * or {@link LineBasedFrameDecoder}. + *
+ * If a custom frame decoder is required, then one needs to be careful when implementing + * one with {@link ByteToMessageDecoder}. Ensure there are enough bytes in the buffer for a + * complete frame by checking {@link ByteBuf#readableBytes()}. If there are not enough bytes + * for a complete frame, return without modify the reader index to allow more bytes to arrive. + *
+ * To check for complete frames without modify the reader index, use methods like {@link ByteBuf#getInt(int)}. + * One MUST use the reader index when using methods like {@link ByteBuf#getInt(int)}. + * For example calling in.getInt(0) is assuming the frame starts at the beginning of the buffer, which + * is not always the case. Use in.getInt(in.readerIndex()) instead. + *
* Be aware that sub-classes of {@link ByteToMessageDecoder} MUST NOT * annotated with {@link @Sharable}. + *
+ * Some methods such as {@link ByteBuf.readBytes(int)} will cause a memory leak if the returned buffer + * is not released or added to the out {@link List}. Use derived buffers like {@link ByteBuf.readSlice(int)} + * to avoid leaking memory. */ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter {