Summary
Creation of HttpClient fails when Selector.open() fails due to unavailability of underlying resources, and HttpClient throws an InternalError. The HttpClient.Builder should document and throw a better exception in this case
Problem
HttpClient::newHttpClient
and HttpClient.Builder::build
throw an InternalError
when creating the HttpClient fails due to underlying resources being not available. For instance, one such case is when Selector.open()
, which is called from the underlying HttpClient implementation constructor, throws an IOException
. This is problematic because the InternalError
that is currently thrown as a result is 1. not documented and 2. not expected by the calling code.
Solution
Methods that create an HttpClient instance should document which exception is thrown if the underlying implementation cannot be instantiated. For backward compatibility this cannot be a checked exception. The proposal is to throw UncheckedIOException
instead of InternalError
.
The following APIs are updated :
- API documentation of
HttpClient.Builder.build()
is updated to declareUncheckedIOException
- API documentation of
HttpClient.newHttpClient()
is updated to declareUncheckedIOException
The UncheckedIOException
will wrap the IOException
thrown by Selector.open()
Specification
src/java.net.http/share/classes/java/net/http/HttpClient.java
/**
* Returns a new {@link HttpClient} built from the current state of this
* builder.
*
* @return a new {@code HttpClient}
*
+ * @throws UncheckedIOException may be thrown if underlying IO resources required
+ * by the implementation cannot be allocated. For instance, if the implementation
+ * requires a {@link Selector}, and opening one fails due to {@linkplain
+ * Selector#open() lack of necessary resources}.
*/
public HttpClient build();
...
/**
* Returns a new {@code HttpClient} with default settings.
*
* <p> Equivalent to {@code newBuilder().build()}.
*
* <p> The default settings include: the "GET" request method, a preference
* of {@linkplain HttpClient.Version#HTTP_2 HTTP/2}, a redirection policy of
* {@linkplain Redirect#NEVER NEVER}, the {@linkplain
* ProxySelector#getDefault() default proxy selector}, and the {@linkplain
* SSLContext#getDefault() default SSL context}.
*
* @implNote The system-wide default values are retrieved at the time the
* {@code HttpClient} instance is constructed. Changing the system-wide
* values after an {@code HttpClient} instance has been built, for
* instance, by calling {@link ProxySelector#setDefault(ProxySelector)}
* or {@link SSLContext#setDefault(SSLContext)}, has no effect on already
* built instances.
*
* @return a new HttpClient
+* @throws UncheckedIOException if necessary underlying IO resources required to
+* {@linkplain Builder#build() build a new HttpClient} cannot be allocated.
*/
public static HttpClient newHttpClient()
...
- csr of
-
JDK-8248006 Revisit exceptions thrown when creating an HttpClient fails due to unavailability of underlying resources
-
- Resolved
-