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?