eclipse-ee4j / eclipse-ee4j/jersey

ChunkedOutput isn't always handled in async context

Open
#5,439 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
730
Forks
382
PR merge metrics
No merged PRs in 30d

Description

The documentation for `ChunkedOutput` (https://eclipse-ee4j.github.io/jersey.github.io/documentation/2.40/async.html#chunked-output) states that the user doesn't need to inject `AsyncResponse`, as `ChunkedOutput` will implicitly use asynchronous processing.

In production, we have come across several occurrences where this is not the case, see the stracktrace below:

```
java.lang.Thread.getStackTrace(Thread.java:1564)
org.glassfish.jersey.message.internal.InboundMessageContext.getWorkers(InboundMessageContext.java:801)
org.glassfish.jersey.server.ChunkedOutput$1.call(ChunkedOutput.java:231)
org.glassfish.jersey.server.ChunkedOutput$1.call(ChunkedOutput.java:198)
org.glassfish.jersey.internal.Errors.process(Errors.java:292)
org.glassfish.jersey.internal.Errors.process(Errors.java:219)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:314)
org.glassfish.jersey.server.ChunkedOutput.flushQueue(ChunkedOutput.java:198)
org.glassfish.jersey.server.ChunkedOutput.setContext(ChunkedOutput.java:412)
org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:699)
org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:380)
org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:370)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:259)
```

See the relevant code in `ServerRuntime`: https://github.com/eclipse-ee4j/jersey/blob/2.x/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java#L258.

This leads to exceptions like `javax.ws.rs.ProcessingException: Response is closed.`. It only seems to happen for small/fast responses (e.g. not a lot of chunks), for larger responses it works without problems.
It seems that Jersey waits with putting the request in async context until the `ChunkedOutput` response object is returned, while there already might be content written to it (in a thread started before returning the `ChunkedOutput` object).
If this is indeed the issue at hand, Jersey should check the resource method return type before invocation and put the request in async context directly when the method returns `ChunkedOutput`.

When we explicitly inject `@AsyncResponse`, the issue doesn't occur anymore.

Questions:
* Is this expected behavior? If so, is `@AsyncResponse` required?
* is the documentation correct? It seems that using `ChunkedOutput` is not always handled asynchronously.

Jersey 2.40 is used.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.