When overriding the HttpClient executor with a custom ThreadPoolExecutor
that uses the default RejectedExecutionHandler.AbortPolicy, the Java HTTP
client (java.net.http.HttpClient) becomes permanently unusable if the
delegate executor rejects a task.

This creates a situation where transient thread pool saturation results in
a non-recoverable client failure.

Reproduction of the issue:
1. The task rejection triggers a call to the error handler (onSubmitFailure)
2. This calls selmgr.abort(failure) with the rejection exception
3. SelectorManager.abort() sets this.closed = true permanently
4. All subsequent HTTP operations fail with "IOException: selector manager
closed"

The client does not recover from this state.

I was able to avoid this by using the DiscardPolicy instead of the
AbortPolicy. However, this behavior was quite a surprise to debug. Is this
behavior intentional, or does it make sense for the HttpClient to treat
task rejection as a recoverable error?

Reply via email to