eclipse-ee4j / eclipse-ee4j/jersey
ChunkedOutput isn't always handled in async context
- 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
Assessment
This issue has not been assessed yet.