io.netty.util.IllegalReferenceCountException: refCnt: ​​0 в HTTP-приложении netty - PullRequest
0 голосов
/ 07 декабря 2018

Я занимаюсь разработкой HTTP-сервера Netty с помощью обработчика REST Джерси.

Ниже приведен инициализатор HTTP -

        ServerBootstrap b = new ServerBootstrap();
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast("codec", new HttpServerCodec());
                        ch.pipeline().addLast("aggregator",
                                new HttpObjectAggregator(512 * 1024));
                        ch.pipeline().addLast("flowcontroller", new FlowControlHandler());
                        String[] pkgs = new String[] { "ads.netty.jersey.resources", "com.fasterxml.jackson.jaxrs.json" };
                        ResourceConfig resourceConfig = new PackagesResourceConfig(pkgs);
                        SimpleHTTPHandler handler = ContainerFactory.createContainer(SimpleHTTPHandler.class, resourceConfig);
                        ch.pipeline().addLast("request",
                                handler);

                    }
                })
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, WriteBufferWaterMark.DEFAULT)
                .childOption(ChannelOption.AUTO_READ, false)
                .childOption(ChannelOption.SO_KEEPALIVE, true);

        ChannelFuture f = b.bind(5055).sync();
        f.channel().closeFuture().sync();

Ниже приведен класс SimpleHTTPHandler -

    import com.sun.jersey.api.core.ResourceConfig;
    import com.sun.jersey.core.header.InBoundHeaders;
    import com.sun.jersey.spi.container.ContainerRequest;
    import com.sun.jersey.spi.container.WebApplication;
    import io.netty.buffer.ByteBufInputStream;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.handler.codec.http.*;
    import java.net.URI;
    import java.util.Arrays;
    import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR;
    import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

    public class SimpleHTTPHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

        private final WebApplication applicationHandler;
        private final ResourceConfig resourceConfig;

        public WebApplication getApplicationHandler() {
            return applicationHandler;
        }

        public ResourceConfig getResourceConfig() {
            return resourceConfig;
        }

        public SimpleHTTPHandler(WebApplication applicationHandler, ResourceConfig resourceConfig) {
            super(false);
            this.applicationHandler = applicationHandler;
            this.resourceConfig = resourceConfig;
        }

        protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) {
            System.out.println("in SimpleHTTPHandler");
            try {
                if (request.uri().equals("/favicon.ico")) return;
                final String base = getBaseUri(request);
                final URI baseUri = new URI(base);
                URI fullRequestUri = new URI(base + request.uri().substring(1));
                System.out.println("baseUri " + baseUri + " fullRequestUri " + fullRequestUri);
                final ContainerRequest cRequest = new ContainerRequest(applicationHandler, request.method().name(), baseUri,
                        fullRequestUri, getHeaders(request), new ByteBufInputStream(request.content()));
                applicationHandler.handleRequest(cRequest, new JerseyResponseWriter(ctx));

            } catch (Exception e) {
                ctx.writeAndFlush(new DefaultFullHttpResponse(HTTP_1_1, INTERNAL_SERVER_ERROR, Unpooled.copiedBuffer(e.toString().getBytes())));
                e.printStackTrace();
            } finally {
                if(!HttpUtil.isKeepAlive(request)) ctx.close();
            }
        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            super.channelReadComplete(ctx);
            ctx.flush();
        }

        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            super.channelActive(ctx);
            ctx.channel().read();
        }

        private InBoundHeaders getHeaders(final FullHttpRequest request) {
            final InBoundHeaders headers = new InBoundHeaders();
            HttpHeaders httpHeaders = request.headers();
            httpHeaders.forEach(e -> headers.put(e.getKey(), Arrays.asList(e.getValue())));
            return headers;
        }

        private String getBaseUri(final FullHttpRequest request) {
            return "http://" + request.headers().get(HttpHeaderNames.HOST) + "/";
        }
    }

Полный код находится в ветке github post-json-error .

Отправляемый мной запрос

    curl -X POST \
    http://localhost:5055/hellonetty/student/text \
    -H 'Content-Type: application/json' \
    -H 'Postman-Token: 3186dfa6-30a5-4148-a978-e9dfe9d1a5c7' \
    -H 'cache-control: no-cache' \
    -d '{"name":"raj", "age": 15 }'

Все работает нормально.Но в консоли я получаю ниже исключение в этой строке -

    io.netty.util.IllegalReferenceCountException: refCnt: 0
        at io.netty.buffer.AbstractByteBuf.ensureAccessible(AbstractByteBuf.java:1417)
        at io.netty.buffer.AbstractByteBuf.ensureWritable0(AbstractByteBuf.java:270)
        at io.netty.buffer.AbstractByteBuf.ensureWritable(AbstractByteBuf.java:265)
        at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1048)
        at io.netty.buffer.ByteBufOutputStream.write(ByteBufOutputStream.java:68)
        at com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.write(ContainerResponse.java:135)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
        at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
        at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
        at java.io.BufferedWriter.flush(BufferedWriter.java:254)
        at com.sun.jersey.core.util.ReaderWriter.writeToAsString(ReaderWriter.java:191)
        at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:128)
        at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:88)
        at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:58)
        at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:302)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1510)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
        at ads.netty.jersey.SimpleHTTPHandler.channelRead0(SimpleHTTPHandler.java:48)
        at ads.netty.jersey.SimpleHTTPHandler.channelRead0(SimpleHTTPHandler.java:17)
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.handler.flow.FlowControlHandler.dequeue(FlowControlHandler.java:187)
        at io.netty.handler.flow.FlowControlHandler.channelRead(FlowControlHandler.java:152)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284)
        at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:581)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)

Я не уверен, какую ошибку я совершаю.Кто-нибудь, пожалуйста, помогите мне.

...