title: java.lang.IndexOutOfBoundsException Exception using Netty in a packet system
body: <p>I am currently programming a system that communicates via packets. This also works. I have one server and theoretically infinite clients. When I start only one client, it works very well, but when I start several, I always get a <code>java.lang.IndexOutOfBoundsException</code> exception after the program has worked for 2-3 minutes.</p>
  <p>The Exception</p>
  <pre><code>WARNUNG: 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.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(77) + length(36) exceeds writerIndex(112): PooledUnsafeDirectByteBuf(ridx: 77, widx: 112, cap: 112)
          at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:478)
          at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
          at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
          at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
          at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
          at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:102)
          at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
          at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
          at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
          at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
          at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
          at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
          at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
          at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:795)
          at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480)
          at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
          at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
          at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
          at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
          at java.lang.Thread.run(Thread.java:748)
  
  Caused by: java.lang.IndexOutOfBoundsException: readerIndex(77) + length(36) exceeds writerIndex(112): PooledUnsafeDirectByteBuf(ridx: 77, widx: 112, cap: 112)
          at io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1442)
          at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1428)
          at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:895)
          at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:903)
          at eu.diamondcloudservice.wrapper.packets.incoming.PacketInCloudServerConnect.read(PacketInCloudServerConnect.java:79)
          at eu.diamondcloudservice.wrapper.network.PacketDecoder.decode(PacketDecoder.java:21)
          at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508)
          at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447)
          ... 19 more
  </code></pre>
  <p>Server <code>main(String[] args)</code></p>
  <pre><code>EventLoopGroup eventLoopGroup = epoll ? (EventLoopGroup) new EpollEventLoopGroup() : (EventLoopGroup) new NioEventLoopGroup();
      try {
          ServerBootstrap serverBootstrap = new ServerBootstrap();
          serverBootstrap.group(eventLoopGroup);
          serverBootstrap.channel(epoll ? EpollServerSocketChannel.class : NioServerSocketChannel.class);
          serverBootstrap.childHandler(new ChannelInitializer&lt;Channel&gt;() {
              protected void initChannel(Channel channel) throws Exception {
                  channel.pipeline().addLast(new NetworkHandler());
              }
          });
          channel = serverBootstrap.bind(networkConfiguration.getPort()).sync().channel();
          channel.closeFuture().syncUninterruptibly();
      } catch (InterruptedException e) {
          e.printStackTrace();
      } finally {
          eventLoopGroup.shutdownGracefully();
      }
  </code></pre>
  <p>Client main(String[] args):</p>
  <pre><code>EventLoopGroup eventLoopGroup = epoll ? (EventLoopGroup) new EpollEventLoopGroup() : (EventLoopGroup) new NioEventLoopGroup();
      try {
  
          io.netty.bootstrap.Bootstrap bootstrap = new Bootstrap();
          bootstrap.group(eventLoopGroup);
          bootstrap.channel(epoll ? EpollSocketChannel.class : NioSocketChannel.class);
          bootstrap.handler(new ChannelInitializer&lt;Channel&gt;() {
              protected void initChannel(Channel channel) throws Exception {
                  channel.pipeline().addLast(new NetworkHandler());
              }
          });
  
          channel = bootstrap.connect(networkConfiguration.getMasterHostname(), networkConfiguration.getMasterPort()).sync().channel();
          packetCaller = new PacketCaller(channel);
          packetCaller.sendPacket(new PacketOutVerify(networkConfiguration.getWrapperName(), networkConfiguration.getKey()));
          channel.closeFuture().syncUninterruptibly();
      } catch (InterruptedException e) {
          e.printStackTrace();
      } finally {
          eventLoopGroup.shutdownGracefully();
      }
  </code></pre>
  <p>channelActive in NetworkHandler:</p>
  <pre><code>public void channelActive(ChannelHandlerContext ctx) throws Exception {
      ctx.pipeline().addLast(new PacketEncoder());
      ctx.pipeline().addLast(new PacketDecoder());
      this.waitingForRegistration.add(ctx.channel());
  }
  </code></pre>
  <p>PacketDecoder</p>
  <pre><code>@Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List&lt;Object&gt; output) throws     Exception {
  int id = byteBuf.readInt();
  Class&lt;? extends Packet&gt; clazz = Wrapper.IN_PACKETS.get(id);
  if (clazz == null) {
    throw new NullPointerException(&quot;Could not find packet by id &quot; + id);
  }
  
  Packet packet = clazz.newInstance();
  packet.read(byteBuf, ctx.channel());
  }
  </code></pre>
  <p>PacketEncoder</p>
  <pre><code>public class PacketEncoder extends MessageToByteEncoder&lt;Packet&gt; {
  @Override
  protected void encode(ChannelHandlerContext ctx, Packet packet, ByteBuf output) throws Exception   {
    int id = Wrapper.OUT_PACKETS.indexOf(packet.getClass());
    if(id == -1)
      throw new NullPointerException(&quot;Couldn't find packet of &quot; + packet.getClass().getName());
  
    output.writeInt(id);
    packet.write(output, ctx.channel());
  }
  }
  </code></pre>