Skip to content

IllegalReferenceCountException: refCnt: 0 (Exec + Jackson) #731

@pierredavidbelanger

Description

@pierredavidbelanger

I am trying to follow the doc to setup thread pool.

I get an error while trying to parse the JSON body in a deferred handler.

Here is a code snippet that demonstrate the problem:

public class App extends Jooby {

    private static class MyValueObject {
        private String field;
        public String getField() { return field; }
        public void setField(String field) { this.field = field; }
    }

    {
        use(new Exec());
        use(new Jackson());

        executor("worker1", Executors.newFixedThreadPool(10));

        post("/myvalue", deferred("worker1", (request) -> {
            MyValueObject myValueObject = request.body(MyValueObject.class);
            Thread.sleep(1000); // I am really busy here!
            return myValueObject;
        }));

        post("/myvalue2", (request) -> {
            MyValueObject myValueObject = request.body(MyValueObject.class);
            Thread.sleep(1000); // I am blocking a server worker thread
            return myValueObject;
        });

        get("/", () -> "Hello World!");
    }

    public static void main(final String[] args) {
        run(App::new, args);
    }
}

When I issue this curl command:

curl -v -X POST \
    -H 'Content-type: application/json' \
    -d '{"field": "a value"}' \
    http://localhost:8080/myvalue

I see this stack trace in the app console output:

[2017-04-19 15:06:14,518]-[pool-20-thread-2] DEBUG org.jooby.spi.HttpHandler - execution of: POST/myvalue resulted in exception
io.netty.util.IllegalReferenceCountException: refCnt: 0
	at io.netty.buffer.AbstractByteBuf.ensureAccessible(AbstractByteBuf.java:1408)
	at io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1394)
	at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1383)
	at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:850)
	at io.netty.buffer.CompositeByteBuf.readBytes(CompositeByteBuf.java:1798)
	at io.netty.buffer.CompositeByteBuf.readBytes(CompositeByteBuf.java:44)
	at io.netty.buffer.ByteBufInputStream.read(ByteBufInputStream.java:179)
	at java.io.InputStream.read(InputStream.java:101)
	at com.google.common.io.ByteStreams.copy(ByteStreams.java:110)
	at org.jooby.internal.BodyReferenceImpl.copy(BodyReferenceImpl.java:98)
	at org.jooby.internal.BodyReferenceImpl.toByteArray(BodyReferenceImpl.java:86)
	at org.jooby.internal.BodyReferenceImpl.<init>(BodyReferenceImpl.java:49)
	at org.jooby.internal.RequestImpl.body(RequestImpl.java:292)
	at org.jooby.Request.body(Request.java:903)
	at ca.routeo.App.lambda$new$0(App.java:38)
	at org.jooby.Deferred.lambda$deferred$2(Deferred.java:445)
	at org.jooby.Deferred.handler(Deferred.java:322)
	at org.jooby.internal.HttpHandlerImpl.lambda$onDeferred$8(HttpHandlerImpl.java:350)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

Is this means we can only access Netty buffer from a Netty thread ?

Also, the exact same code, when not deferred (/myvalue2 handler), is working.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions