Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8251198

Throw UncheckedIOException when creating an HttpClient fails due to unavailability of underlying resources

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 16
    • core-libs
    • None
    • behavioral
    • low
    • Java API
    • SE

      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 declare UncheckedIOException
      • API documentation of HttpClient.newHttpClient() is updated to declare UncheckedIOException

      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()

      ...

            ryadav Rahul Yadav
            dfuchs Daniel Fuchs
            Daniel Fuchs
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: