http-client-branch: javadoc refresh and minor fixes http-client-branch
authorchegar
Thu, 08 Feb 2018 20:58:35 +0000
branchhttp-client-branch
changeset 56097 15dc43936d39
parent 56094 881f0ecb513f
child 56098 e1890248eafe
http-client-branch: javadoc refresh and minor fixes
make/common/Modules.gmk
src/java.net.http/share/classes/java/net/http/HttpClient.java
src/java.net.http/share/classes/java/net/http/HttpRequest.java
src/java.net.http/share/classes/java/net/http/HttpResponse.java
src/java.net.http/share/classes/java/net/http/package-info.java
src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java
test/jdk/java/net/httpclient/MappedResponseSubscriber.java
test/jdk/java/net/httpclient/SubscriberPublisherAPIExceptions.java
--- a/make/common/Modules.gmk	Wed Feb 07 22:49:25 2018 +0000
+++ b/make/common/Modules.gmk	Thu Feb 08 20:58:35 2018 +0000
@@ -143,7 +143,7 @@
 # DOCS_MODULES defines the root modules for javadoc generation.
 # All of their `require transitive` modules directly and indirectly will be included.
 DOCS_MODULES += \
-    java.net.http\
+    java.net.http \
     java.se.ee \
     java.smartcardio \
     jdk.accessibility \
--- a/src/java.net.http/share/classes/java/net/http/HttpClient.java	Wed Feb 07 22:49:25 2018 +0000
+++ b/src/java.net.http/share/classes/java/net/http/HttpClient.java	Thu Feb 08 20:58:35 2018 +0000
@@ -31,6 +31,9 @@
 import java.net.InetSocketAddress;
 import java.net.Proxy;
 import java.net.ProxySelector;
+import java.net.URLPermission;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
@@ -45,37 +48,81 @@
 /**
  * An HTTP Client.
  *
- * <p> An {@code HttpClient} can be used to send requests and retrieve their
- * responses. An {@code HttpClient} is created through a {@link
- * HttpClient#newBuilder() builder}. The builder can be used to configure
- * per-client state, like: the preferred protocol version ( HTTP/1.1 or HTTP/2 ),
- * whether to follow redirects, a proxy, an authenticator, etc. Once built, an
- * {@code HttpClient} is immutable, and can be used to send multiple requests.
+ * <p> An {@code HttpClient} can be used to send {@linkplain HttpRequest
+ * requests} and retrieve their {@linkplain HttpResponse responses}. An {@code
+ * HttpClient} is created through a {@link HttpClient#newBuilder() builder}. The
+ * builder can be used to configure per-client state, like: the preferred
+ * protocol version ( HTTP/1.1 or HTTP/2 ), whether to follow redirects, a
+ * proxy, an authenticator, etc. Once built, an {@code HttpClient} is immutable,
+ * and can be used to send multiple requests.
  *
  * <p> An {@code HttpClient} provides configuration information, and resource
  * sharing, for all requests send through it.
  *
- * <p>For Example:
+ * <p> Requests can be made either synchronously or asynchronously:
+ * <ul>
+ *     <li>{@link HttpClient#send(HttpRequest, BodyHandler)} blocks
+ *     until the request has been sent and the response has been received.</li>
+ *
+ *     <li>{@link HttpClient#sendAsync(HttpRequest, BodyHandler)} sends the
+ *     request and receives the response asynchronously. The {@code sendAsync}
+ *     method returns immediately with a {@linkplain CompletableFuture
+ *     CompletableFuture}&lt;{@linkplain HttpResponse}&gt;. The {@code
+ *     CompletableFuture} completes when the response becomes available. The
+ *     returned {@code CompletableFuture} can be combined in different ways to
+ *     declare dependencies among several asynchronous tasks.</li>
+ * </ul>
+ *
+ * <p> A {@linkplain BodyHandler BodyHandler} must be supplied for each {@code
+ * HttpRequest} sent. The {@code BodyHandler} determines how to handle the
+ * response body, if any. Once an {@linkplain HttpResponse} is received, the
+ * headers, response code, and body (typically) are available. Whether the
+ * response body bytes has been read or not depends on the type {@code <T>} of
+ * the response body.
+ *
+ * <p><b>Synchronous Example</b>
  * <pre>{@code    HttpClient client = HttpClient.newBuilder()
- *        .version(Version.HTTP_2)
+ *        .version(Version.HTTP_1)
  *        .followRedirects(Redirect.SAME_PROTOCOL)
- *        .proxy(ProxySelector.of(new InetSocketAddress("proxy.com", 8080)))
+ *        .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
  *        .authenticator(Authenticator.getDefault())
  *        .build();
+ *   HttpResponse<String> response = client.send(request, BodyHandler.asString());
+ *   System.out.println(response.statusCode());
+ *   System.out.println(response.body());  }</pre>
  *
- *   HttpRequest request = HttpRequest.newBuilder()
- *        .uri(URI.create("http://foo.com/"))
+ * <p><b>Asynchronous Example</b>
+ * <pre>{@code    HttpRequest request = HttpRequest.newBuilder()
+ *        .uri(URI.create("https://foo.com/"))
  *        .timeout(Duration.ofMinutes(1))
  *        .header("Content-Type", "application/json")
  *        .POST(BodyPublisher.fromFile(Paths.get("file.json")))
  *        .build();
- *
  *   client.sendAsync(request, BodyHandler.asString())
  *        .thenApply(HttpResponse::body)
  *        .thenAccept(System.out::println)
  *        .join();  }</pre>
  *
- * <p> See {@link HttpRequest} for further examples of usage of this API.
+ * <p> <a id="securitychecks"></a><b>Security checks</b></a>
+ *
+ * <p> If a security manager is present then security checks are performed by
+ * the HTTP Client's sending methods. An appropriate {@link URLPermission} is
+ * required to access the destination server, and proxy server if one has
+ * been configured. The form of the {@code URLPermission} required to access a
+ * proxy has a {@code method} parameter of {@code "CONNECT"} (for all kinds of
+ * proxying) and a {@code URL} string of the form {@code "socket://host:port"}
+ * where host and port specify the proxy's address.
+ *
+ * @implNote If an explicit {@linkplain HttpClient.Builder#executor(Executor)
+ * executor} has not been set for an {@code HttpClient}, and a security manager
+ * has been installed, then the default executor will execute asynchronous and
+ * dependent tasks in a context that is granted no permissions. Custom
+ * {@linkplain HttpRequest.BodyPublisher request body publishers}, {@linkplain
+ * HttpResponse.BodyHandler response body handlers}, {@linkplain
+ * HttpResponse.BodySubscriber response body subscribers}, and {@linkplain
+ * WebSocket.Listener WebSocket Listeners}, if executing operations that require
+ * privileges, should do so within an appropriate {@linkplain
+ * AccessController#doPrivileged(PrivilegedAction) privileged context}.
  *
  * @since 11
  */
@@ -87,7 +134,7 @@
     protected HttpClient() {}
 
     /**
-     * Returns a new HttpClient with default settings.
+     * Returns a new {@code HttpClient} with default settings.
      *
      * <p> Equivalent to {@code newBuilder().build()}.
      *
@@ -113,14 +160,14 @@
     /**
      * Creates a new {@code HttpClient} builder.
      *
-     * @return a {@code HttpClient.Builder}
+     * @return an {@code HttpClient.Builder}
      */
     public static Builder newBuilder() {
         return new HttpClientBuilderImpl();
     }
 
     /**
-     * A builder of immutable {@link HttpClient}s.
+     * A builder of {@link HttpClient}s.
      *
      * <p> Builders are created by invoking {@linkplain HttpClient#newBuilder()
      * newBuilder}. Each of the setter methods modifies the state of the builder
@@ -254,20 +301,20 @@
         /**
          * Sets a {@link java.net.ProxySelector}.
          *
-         * @apiNote {@link ProxySelector#of(InetSocketAddress)}
+         * @apiNote {@link ProxySelector#of(InetSocketAddress) ProxySelector::of}
          * provides a {@code ProxySelector} which uses a single proxy for all
          * requests. The system-wide proxy selector can be retrieved by
          * {@link ProxySelector#getDefault()}.
          *
          * @implNote
-         * If this method is not invoked prior to {@linkplain #build()
-         * building}, then newly built clients will use the {@linkplain
-         * ProxySelector#getDefault() default proxy selector}, which
-         * is normally adequate for client applications. This default
-         * behavior can be turned off by supplying an explicit proxy
-         * selector to this method, such as {@link #NO_PROXY} or one
-         * returned by {@link ProxySelector#of(InetSocketAddress)},
-         * before calling {@link #build()}.
+         * If this method is not invoked prior to {@linkplain #build() building},
+         * then newly built clients will use the {@linkplain
+         * ProxySelector#getDefault() default proxy selector}, which is usually
+         * adequate for client applications. This default behavior can be turned
+         * off by supplying an explicit proxy selector to this method, such as
+         * {@link #NO_PROXY} or one returned by {@linkplain
+         * ProxySelector#of(InetSocketAddress) ProxySelector::of}, before
+         * {@linkplain #build() building}.
          *
          * @param selector the ProxySelector
          * @return this builder
@@ -442,27 +489,27 @@
      * handler ).
      *
      * @param <T> the response body type
-     * @param req the request
+     * @param request the request
      * @param responseBodyHandler the response body handler
-     * @return the response body
+     * @return the response
      * @throws IOException if an I/O error occurs when sending or receiving
      * @throws InterruptedException if the operation is interrupted
      * @throws IllegalArgumentException if the request method is not supported
      * @throws SecurityException If a security manager has been installed
      *          and it denies {@link java.net.URLPermission access} to the
      *          URL in the given request, or proxy if one is configured.
-     *          See HttpRequest for further information about
-     *          <a href="HttpRequest.html#securitychecks">security checks</a>.
+     *          See <a href="#securitychecks">security checks</a> for further
+     *          information.
      */
     public abstract <T> HttpResponse<T>
-    send(HttpRequest req, HttpResponse.BodyHandler<T> responseBodyHandler)
+    send(HttpRequest request, HttpResponse.BodyHandler<T> responseBodyHandler)
         throws IOException, InterruptedException;
 
     /**
-     * Sends the given request asynchronously using this client and the given
-     * response handler.
+     * Sends the given request asynchronously using this client with the given
+     * response body handler.
      *
-     * <p> Equivalent to {@code sendAsync(request, responseBodyHandler, null)}.
+     * <p> Equivalent to: {@code sendAsync(request, responseBodyHandler, null)}.
      *
      * @param <T> the response body type
      * @param request the request
@@ -492,8 +539,8 @@
      * <li>{@link SecurityException} - If a security manager has been installed
      *          and it denies {@link java.net.URLPermission access} to the
      *          URL in the given request, or proxy if one is configured.
-     *          See HttpRequest for further information about
-     *          <a href="HttpRequest.html#securitychecks">security checks</a>.</li>
+     *          See <a href="#securitychecks">security checks</a> for further
+     *          information.</li>
      * </ul>
      *
      * @param <T> the response body type
@@ -511,24 +558,20 @@
      * Creates a new {@code WebSocket} builder (optional operation).
      *
      * <p> <b>Example</b>
-     * <pre>{@code
-     *     HttpClient client = HttpClient.newHttpClient();
+     * <pre>{@code      HttpClient client = HttpClient.newHttpClient();
      *     CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()
-     *             .buildAsync(URI.create("ws://websocket.example.com"), listener);
-     * }</pre>
+     *             .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre>
      *
      * <p> Finer control over the WebSocket Opening Handshake can be achieved
      * by using a custom {@code HttpClient}.
      *
      * <p> <b>Example</b>
-     * <pre>{@code
-     *     InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80);
+     * <pre>{@code      InetSocketAddress addr = new InetSocketAddress("proxy.example.com", 80);
      *     HttpClient client = HttpClient.newBuilder()
      *             .proxy(ProxySelector.of(addr))
      *             .build();
      *     CompletableFuture<WebSocket> ws = client.newWebSocketBuilder()
-     *             .buildAsync(URI.create("ws://websocket.example.com"), listener);
-     * }</pre>
+     *             .buildAsync(URI.create("ws://websocket.example.com"), listener); }</pre>
      *
      * <p> A {@code WebSocket.Builder} returned from this method is not safe for
      * use by multiple threads without external synchronization.
--- a/src/java.net.http/share/classes/java/net/http/HttpRequest.java	Wed Feb 07 22:49:25 2018 +0000
+++ b/src/java.net.http/share/classes/java/net/http/HttpRequest.java	Thu Feb 08 20:58:35 2018 +0000
@@ -52,60 +52,33 @@
 /**
  * An HTTP request.
  *
- * <p> An {@code HttpRequest} instance is built through a {@code HttpRequest}
+ * <p> An {@code HttpRequest} instance is built through an {@code HttpRequest}
  * {@linkplain HttpRequest.Builder builder}. An {@code HttpRequest} builder
- * is obtained from one of the {@link HttpRequest#newBuilder(URI) newBuilder}
+ * is obtained from one of the {@linkplain HttpRequest#newBuilder(URI) newBuilder}
  * methods. A request's {@linkplain URI}, headers, and body can be set. Request
- * bodies are provided through a {@link BodyPublisher} object supplied to the
- * {@link Builder#DELETE(BodyPublisher) DELETE},
- * {@link Builder#POST(BodyPublisher) POST} or
- * {@link Builder#PUT(BodyPublisher) PUT} methods.
+ * bodies are provided through a {@linkplain BodyPublisher BodyPublisher}
+ * supplied to one of the {@linkplain Builder#DELETE(BodyPublisher) DELETE},
+ * {@linkplain Builder#POST(BodyPublisher) POST} or
+ * {@linkplain Builder#PUT(BodyPublisher) PUT} methods.
  * Once all required parameters have been set in the builder, {@link
  * Builder#build() build} will return the {@code HttpRequest}. Builders can be
  * copied and modified many times in order to build multiple related requests
  * that differ in some parameters.
  *
- * <p> <b>Example HTTP interactions:</b>
- * <pre>{@code    // GET
- *    HttpResponse<String> response = client.send(
- *          HttpRequest.newBuilder(new URI("http://www.foo.com/"))
- *                     .headers("Foo", "foovalue", "Bar", "barvalue")
- *                     .GET()
- *                     .build(),
- *          BodyHandler.asString()
- *    );
- *    int statusCode = response.statusCode();
- *    String body = response.body();
+ * <p><b>Example:</b> GET request that prints the response body as a String
+ * <pre>{@code    HttpClient client = HttpClient.newHttpClient();
+ *   HttpRequest request = HttpRequest.newBuilder()
+ *         .uri(URI.create("http://foo.com/"))
+ *         .build();
+ *   client.sendAsync(request, BodyHandler.asString())
+ *         .thenApply(HttpResponse::body)
+ *         .thenAccept(System.out::println)
+ *         .join(); }</pre>
  *
- *    // POST
- *    HttpResponse<Path> response = client.send(
- *          HttpRequest.newBuilder(new URI("http://www.foo.com/"))
- *                     .headers("Foo", "foovalue", "Bar", "barvalue")
- *                     .POST(BodyPublisher.fromString("Hello world"))
- *                     .build(),
- *          BodyHandler.asFile(Paths.get("/path"))
- *    );
- *    int statusCode = response.statusCode();
- *    Path body = response.body(); // should be "/path" }</pre>
- *
- * <p> The request is sent and the response obtained by invoking one of the
- * following methods in {@link HttpClient}.
- * <ul><li>{@link HttpClient#send(HttpRequest, BodyHandler)} blocks
- * until the entire request has been sent and the response has been received.</li>
- * <li>{@link HttpClient#sendAsync(HttpRequest, BodyHandler)} sends the
- * request and receives the response asynchronously. Returns immediately with a
- * {@linkplain CompletableFuture CompletableFuture}&lt;{@linkplain HttpResponse}&gt;.</li>
- * </ul>
- *
- * <p> Once a {@link HttpResponse} is received, the headers, response code,
- * and body (typically) are available. Whether the response body bytes has been
- * read or not depends on the type {@code <T>} of the response body. See below.
- *
- * <p> <b>Request bodies</b>
+ * <p><b>Request bodies</b>
  *
  * <p> Request bodies can be sent using one of the convenience request publisher
- * implementations, provided in {@link BodyPublisher}. Alternatively, a custom
- * Publisher implementation can be used.
+ * implementations, provided in {@linkplain BodyPublisher BodyPublisher}.
  * <ul>
  * <li>{@link BodyPublisher#fromByteArray(byte[]) fromByteArray(byte[])} from byte array</li>
  * <li>{@link BodyPublisher#fromByteArrays(Iterable) fromByteArrays(Iterable)}
@@ -118,114 +91,7 @@
  * <li>{@link BodyPublisher#noBody() noBody()} no request body is sent</li>
  * </ul>
  *
- * <p> <b>Response bodies</b>
- *
- * <p> Responses bodies are handled at two levels. When sending the request,
- * a response {@linkplain BodyHandler body handler} is specified. This is a
- * function that will be called with the response status code and headers, once
- * they are received. This function must to return a {@link
- * HttpResponse.BodySubscriber}{@code <T>} which is used to read the response
- * body bytes, converting them into an instance of {@code T}. After this occurs,
- * the response becomes available in a {@link HttpResponse}, and the {@link
- * HttpResponse#body()} can be invoked to obtain the actual body. Some
- * implementations and examples of usage of both {@link
- * HttpResponse.BodySubscriber} and {@link HttpResponse.BodyHandler} are
- * provided in {@link HttpResponse}:
- *
- * <p> <b>Some of the pre-defined body handlers</b><br>
- * <ul>
- * <li>{@link BodyHandler#asByteArray() BodyHandler.asByteArray()}
- * stores the body in a byte array</li>
- * <li>{@link BodyHandler#asString() BodyHandler.asString()}
- * stores the body as a String </li>
- * <li>{@link BodyHandler#asFile(java.nio.file.Path)
- * BodyHandler.asFile(Path)} stores the body in a named file</li>
- * <li>{@link BodyHandler#replace(Object) BodyHandler.replace(Objectt)}
- * discards the response body and returns the given replacement value instead.</li>
- * </ul>
- *
- * <p> <b>Blocking/asynchronous behavior and thread usage</b>
- *
- * <p> There are two styles of request sending: <i>synchronous</i> and
- * <i>asynchronous</i>. {@link HttpClient#send(HttpRequest, HttpResponse.BodyHandler) }
- * blocks the calling thread until the request has been sent and the response received.
- *
- * <p> {@link HttpClient#sendAsync(HttpRequest, HttpResponse.BodyHandler)} is
- * asynchronous and returns immediately with a {@link CompletableFuture}&lt;{@link
- * HttpResponse}&gt; and when this object completes (possibly in a different
- * thread) the response has been received.
- *
- * <p> Instances of {@code CompletableFuture} can be combined in different ways
- * to declare the dependencies among several asynchronous tasks, while allowing
- * for the maximum level of parallelism to be utilized.
- *
- * <p> <a id="securitychecks"></a><b>Security checks</b></a>
- *
- * <p> If a security manager is present then security checks are performed by
- * the HTTP Client's sending methods. An appropriate {@link URLPermission} is
- * required to access the destination server, and proxy server if one has
- * been configured. The {@code URLPermission} form used to access proxies uses a
- * method parameter of {@code "CONNECT"} (for all kinds of proxying) and a URL
- * string  of the form {@code "socket://host:port"} where host and port specify
- * the proxy's address.
- *
- * <p> In this implementation, if an explicit {@linkplain
- * HttpClient.Builder#executor(Executor) executor} has not been set for an
- * {@code HttpClient}, and a security manager has been installed, then the
- * default executor will execute asynchronous and dependent tasks in a context
- * that is granted no permissions. Custom {@linkplain HttpRequest.BodyPublisher
- * request body publishers}, {@linkplain HttpResponse.BodyHandler response body
- * handlers}, {@linkplain HttpResponse.BodySubscriber response body subscribers},
- * and {@linkplain WebSocket.Listener WebSocket Listeners}, if executing
- * operations that require privileges, should do so  within an appropriate
- * {@linkplain AccessController#doPrivileged(PrivilegedAction) privileged context}.
- *
- * <p> <b>Examples</b>
- * <pre>{@code    HttpClient client = HttpClient.newHttpClient();
- *
- *    HttpRequest request = HttpRequest
- *            .newBuilder(URI.create("http://www.foo.com/"))
- *            .POST(BodyPublisher.fromString("Hello world"))
- *            .build();
- *
- *    HttpResponse<Path> response =
- *        client.send(request, BodyHandler.asFile(Paths.get("/path")));
- *
- *    Path body = response.body(); }</pre>
- *
- * <p><b>Asynchronous Example</b>
- *
- * <p> The above example will work asynchronously, if {@link HttpClient#sendAsync
- * (HttpRequest, HttpResponse.BodyHandler) sendAsync} is used instead of
- * {@link HttpClient#send(HttpRequest,HttpResponse.BodyHandler) send}
- * in which case the returned object is a {@link CompletableFuture}{@code <HttpResponse>}
- * instead of {@link HttpResponse}. The following example shows how multiple requests
- * can be sent asynchronously. It also shows how dependent asynchronous operations
- * (receiving response, and receiving response body) can be chained easily using
- * one of the many methods in {@code CompletableFuture}.
- * <pre>{@code     // fetch a list of target URIs asynchronously and store them in Files.
- *
- *    List<URI> targets = ...
- *
- *    List<CompletableFuture<File>> futures = targets
- *        .stream()
- *        .map(target -> client
- *                .sendAsync(
- *                    HttpRequest.newBuilder(target)
- *                               .GET()
- *                               .build(),
- *                    BodyHandler.asFile(Paths.get("base", target.getPath())))
- *                .thenApply(response -> response.body())
- *                .thenApply(path -> path.toFile()))
- *        .collect(Collectors.toList());
- *
- *    // all async operations waited for here
- *
- *    CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]))
- *        .join();
- *
- *    // all elements of futures have completed and can be examined.
- *    // Use File.exists() to check whether file was successfully downloaded }</pre>
+ * <p> Alternatively, a custom {@code BodyPublisher} implementation can be used.
  *
  * @since 11
  */
@@ -237,7 +103,7 @@
     protected HttpRequest() {}
 
     /**
-     * A builder of {@linkplain HttpRequest HTTP Requests}.
+     * A builder of {@linkplain HttpRequest HTTP requests}.
      *
      * <p> Instances of {@code HttpRequest.Builder} are created by calling {@link
      * HttpRequest#newBuilder(URI)} or {@link HttpRequest#newBuilder()}.
@@ -245,16 +111,15 @@
      * <p> Each of the setter methods in this class modifies the state of the
      * builder and returns <i>this</i> (ie. the same instance). The methods are
      * not synchronized and should not be called from multiple threads without
-     * external synchronization.
+     * external synchronization. The {@linkplain #build() build} method returns
+     * a new {@code HttpRequest} each time it is invoked. Once built an {@code
+     * HttpRequest} is immutable, and can be sent multiple times.
      *
      * <p> Note, that not all request headers may be set by user code. Some are
      * restricted for security reasons and others such as the headers relating
-     * to authentication, redirection and cookie management are managed by
+     * to authentication, redirection and cookie management may be managed by
      * specific APIs rather than through directly user set headers.
      *
-     * <p> The {@linkplain #build() build} method returns a new {@code
-     * HttpRequest} each time it is invoked.
-     *
      * @since 11
      */
     public abstract static class Builder {
@@ -447,7 +312,7 @@
     }
 
     /**
-     * Creates a {@code HttpRequest} builder.
+     * Creates an {@code HttpRequest} builder with the given URI.
      *
      * @param uri the request URI
      * @return a new request builder
@@ -458,7 +323,7 @@
     }
 
     /**
-     * Creates a {@code HttpRequest} builder.
+     * Creates an {@code HttpRequest} builder.
      *
      * @return a new request builder
      */
@@ -493,15 +358,15 @@
     public abstract Optional<Duration> timeout();
 
     /**
-     * Returns this request's {@link HttpRequest.Builder#expectContinue(boolean)
-     * expect continue } setting.
+     * Returns this request's {@linkplain HttpRequest.Builder#expectContinue(boolean)
+     * expect continue} setting.
      *
      * @return this request's expect continue setting
      */
     public abstract boolean expectContinue();
 
     /**
-     * Returns this request's request {@code URI}.
+     * Returns this request's {@code URI}.
      *
      * @return this request's URI
      */
@@ -571,31 +436,31 @@
     }
 
     /**
-     * A Publisher which converts high level Java objects into flows of
-     * byte buffers suitable for sending as request bodies.
+     * A {@code BodyPublisher} converts high-level Java objects into a flow of
+     * byte buffers suitable for sending as a request body.
      *
-     * <p> The {@code BodyPublisher} class implements {@link Flow.Publisher
-     * Flow.Publisher&lt;ByteBuffer&gt;} which means that a {@code BodyPublisher}
+     * <p> The {@code BodyPublisher} interface extends {@link Flow.Publisher
+     * Flow.Publisher&lt;ByteBuffer&gt;}, which means that a {@code BodyPublisher}
      * acts as a publisher of {@linkplain ByteBuffer byte buffers}.
      *
-     * <p> The HTTP client implementation subscribes to the publisher in order
-     * to receive the flow of outgoing data buffers. The normal semantics of
-     * {@link Flow.Subscriber} and {@link Flow.Publisher} are implemented by the
-     * library and are expected from publisher implementations. Each outgoing
-     * request results in one {@code Subscriber} subscribing to the {@code
-     * BodyPublisher} in order to provide the sequence of byte buffers
-     * containing the request body.
-     * Instances of {@code ByteBuffer} published  by the publisher must be
-     * allocated by the publisher, and must not be accessed after being handed
-     * over to the library.
-     * These subscriptions complete normally when the request is fully sent,
-     * and can be canceled or terminated early through error. If a request
-     * needs to be resent for any reason, then a new subscription is created
-     * which is expected to generate the same data as before.
+     * <p> When sending a request that contains a body, the HTTP Client
+     * subscribes to the request's {@code BodyPublisher} in order to receive the
+     * flow of outgoing request body data. The normal semantics of {@link
+     * Flow.Subscriber} and {@link Flow.Publisher} are implemented by the HTTP
+     * Client and are expected from {@code BodyPublisher} implementations. Each
+     * outgoing request results in one HTTP Client {@code Subscriber}
+     * subscribing to the {@code BodyPublisher} in order to provide the sequence
+     * of byte buffers containing the request body. Instances of {@code
+     * ByteBuffer} published by the publisher must be allocated by the
+     * publisher, and must not be accessed after being published to the HTTP
+     * Client. These subscriptions complete normally when the request body is
+     * fully sent, and can be canceled or terminated early through error. If a
+     * request needs to be resent for any reason, then a new subscription is
+     * created which is expected to generate the same data as before.
      *
-     * <p> A publisher that reports a {@linkplain #contentLength() content
-     * length} of {@code 0} may not be subscribed to by the HTTP client
-     * implementation, as it has effectively no data to publish.
+     * <p> A {@code BodyPublisher} that reports a {@linkplain #contentLength()
+     * content length} of {@code 0} may not be subscribed to by the HTTP Client,
+     * as it has effectively no data to publish.
      */
     public interface BodyPublisher extends Flow.Publisher<ByteBuffer> {
 
--- a/src/java.net.http/share/classes/java/net/http/HttpResponse.java	Wed Feb 07 22:49:25 2018 +0000
+++ b/src/java.net.http/share/classes/java/net/http/HttpResponse.java	Thu Feb 08 20:58:35 2018 +0000
@@ -57,37 +57,22 @@
 import static jdk.internal.net.http.common.Utils.charsetFrom;
 
 /**
- * Represents a response to a {@link HttpRequest}.
- *
- * <p> A {@code HttpResponse} is available when the response status code and
- * headers have been received, and typically after the response body has also
- * been received. This depends on the response body handler provided when
- * sending the request. In all cases, the response body handler is invoked
- * before the body is read. This gives applications an opportunity to decide
- * how to handle the body.
- *
- * <p> Methods are provided in this class for accessing the response headers,
- * and response body.
- *
- * <p><b>Response handlers and subscribers</b>
+ * An HTTP response.
  *
- * <p> Response bodies are handled at two levels. Application code supplies a
- * response handler ({@link BodyHandler}) which may examine the response status
- * code and headers, and which then returns a {@link BodySubscriber} to actually
- * read (or discard) the body and convert it into some useful Java object type.
- * The handler can return one of the pre-defined subscriber types, or a custom
- * subscriber, or if the body is to be discarded it can call {@link
- * BodySubscriber#discard() discard} and return a subscriber which
- * discards the response body. Static implementations of both handlers and
- * subscribers are provided in {@linkplain BodyHandler BodyHandler} and
- * {@linkplain BodySubscriber BodySubscriber} respectively. In all cases, the
- * handler functions provided are convenience implementations which ignore the
- * supplied status code and headers and return the relevant pre-defined {@code
- * BodySubscriber}.
+ * <p> An {@code HttpResponse} is not created directly, but rather returned as
+ * a result of sending an {@linkplain HttpRequest}. An {@code HttpResponse} is
+ * made available when the response status code and headers have been received,
+ * and typically after the response body has also been completely received.
+ * Whether or not the {@code HttpResponse} is made available before the response
+ * body has been completely received depends on the {@linkplain BodyHandler
+ * BodyHandler} provided when sending the {@code HttpRequest}.
  *
- * <p> See {@link BodyHandler} for example usage.
+ * <p> This class provides methods for accessing the response status code,
+ * headers, the response body, and the {@code HttpRequest} corresponding
+ * to this response.
+ **
+ * @param <T> the response body type
  *
- * @param <T> the response body type
  * @since 11
  */
 public abstract class HttpResponse<T> {
@@ -178,76 +163,77 @@
     /**
      * A handler for response bodies.
      *
-     * <p> This is a function that takes two parameters: the response status code,
-     * and the response headers, and which returns a {@linkplain BodySubscriber}.
-     * The function is always called just before the response body is read. Its
-     * implementation may examine the status code or headers and must decide,
-     * whether to accept the response body or discard it, and if accepting it,
-     * exactly how to handle it.
+     * <p> The {@code BodyHandler} interface allows inspection of the response
+     * code and headers, before the actual response body is received, and is
+     * responsible for creating the response {@linkplain BodySubscriber
+     * BodySubscriber}. The {@code BodySubscriber} consumes the actual response
+     * body bytes and converts them into a higher-level Java type.
      *
-     * <p> Some pre-defined implementations which do not utilize the status code
-     * or headers (meaning the body is always accepted) are defined:
+     * <p> A {@code BodyHandler} is a function that takes two parameters: the
+     * response status code and the response headers; and which returns a
+     * {@code BodySubscriber}. The {@code BodyHandler} is invoked when the
+     * response status code and headers are available, but before the response
+     * body bytes are received.
+     *
+     * <p> A number of convenience static factory methods are provided that
+     * return pre-defined implementations that do not examine the status code
+     * (meaning the body is always accepted):
      * <ul><li>{@link #asByteArray() }</li>
      * <li>{@link #asByteArrayConsumer(java.util.function.Consumer)
      * asByteArrayConsumer(Consumer)}</li>
      * <li>{@link #asString(java.nio.charset.Charset) asString(Charset)}</li>
-     * <li>{@link #asFile(Path, OpenOption...)
-     * asFile(Path,OpenOption...)}</li>
+     * <li>{@link #asFile(Path, OpenOption...) asFile(Path,OpenOption...)}</li>
      * <li>{@link #asFileDownload(java.nio.file.Path,OpenOption...)
      * asFileDownload(Path,OpenOption...)}</li>
      * <li>{@link #asInputStream() asInputStream()}</li>
      * <li>{@link #discard() }</li>
      * <li>{@link #replace(Object) }</li>
-     * <li>{@link #buffering(BodyHandler, int)
-     * buffering(BodyHandler,int)}</li>
+     * <li>{@link #buffering(BodyHandler, int) buffering(BodyHandler,int)}</li>
      * </ul>
      *
-     * <p> These implementations return the equivalent {@link BodySubscriber}.
-     * Alternatively, the handler can be used to examine the status code
-     * or headers and return different body subscribers as appropriate.
+     * <p> These implementations return an equivalently named {@code
+     * BodySubscriber}. Alternatively, a custom handler can be used to examine
+     * the status code or headers, and return different body subscribers as
+     * appropriate.
      *
-     * <p><b>Examples of handler usage</b>
+     * <p><b>Examples:</b>
      *
-     * <p> The first example uses one of the predefined handler functions which
-     * ignores the response headers and status, and always process the response
-     * body in the same way.
-     * <pre>
-     * {@code
-     *      HttpResponse<Path> resp = HttpRequest
-     *              .create(URI.create("http://www.foo.com"))
-     *              .GET()
-     *              .response(BodyHandler.asFile(Paths.get("/tmp/f")));
-     * }
-     * </pre>
-     * Note, that even though these pre-defined handlers ignore the status code
-     * and headers, this information is still accessible from the
-     * {@code HttpResponse} when it is returned.
+     * <p> The first example uses one of the predefined handler functions that
+     * always process the response body in the same way.
+     * <pre>{@code   HttpRequest request = HttpRequest.newBuilder()
+     *        .uri(URI.create("http://www.foo.com/"))
+     *        .build();
+     *  client.sendAsync(request, BodyHandler.asFile(Paths.get("/tmp/f")))
+     *        .thenApply(HttpResponse::body)
+     *        .thenAccept(System.out::println) }</pre>
+     * Note, that even though these pre-defined handlers do not examine the
+     * response code, the response code and headers are always retrievable from
+     * the {@linkplain HttpResponse}, when it is returned.
      *
      * <p> In the second example, the function returns a different subscriber
      * depending on the status code.
-     * <pre>
-     * {@code
-     *      HttpResponse<Path> resp1 = HttpRequest
-     *              .create(URI.create("http://www.foo.com"))
-     *              .GET()
-     *              .response(
-     *                  (status, headers) -> status == 200
+     * <pre>{@code   HttpRequest request = HttpRequest.newBuilder()
+     *        .uri(URI.create("http://www.foo.com/"))
+     *        .build();
+     *  BodyHandler bodyHandler = (status, headers) -> status == 200
      *                      ? BodySubscriber.asFile(Paths.get("/tmp/f"))
      *                      : BodySubscriber.replace(Paths.get("/NULL")));
-     * }
-     * </pre>
+     *  client.sendAsync(request, bodyHandler))
+     *        .thenApply(HttpResponse::body)
+     *        .thenAccept(System.out::println) }</pre>
      *
      * @param <T> the response body type
      */
     @FunctionalInterface
     public interface BodyHandler<T> {
         /**
-         * Returns a {@link BodySubscriber BodySubscriber} considering the given
-         * response status code and headers. This method is always called before
-         * the body is read and its implementation can decide to keep the body
-         * and store it somewhere, or else discard it by returning the {@code
-         * BodySubscriber} returned from {@link BodySubscriber#discard()
-         * discard}.
+         * Returns a {@linkplain BodySubscriber BodySubscriber} considering the
+         * given response status code and headers. This method is invoked before
+         * the actual response body bytes are read and its implementation must
+         * return a {@code BodySubscriber} to consume the response body bytes.
+         *
+         * <p> The response body can be discarded using one of {@linkplain
+         * #discard() discard} or {@linkplain #replace(Object) replace}.
          *
          * @param statusCode the HTTP status code received
          * @param responseHeaders the response headers received
@@ -272,12 +258,10 @@
          * BodySubscriber} and {@code Flow.Subscriber}.
          *
          * <p> For example:
-         * <pre> {@code
-         *  TextSubscriber subscriber = new TextSubscriber();
+         * <pre> {@code  TextSubscriber subscriber = new TextSubscriber();
          *  HttpResponse<Void> response = client.sendAsync(request,
          *      BodyHandler.fromSubscriber(subscriber)).join();
-         *  System.out.println(response.statusCode());
-         * }</pre>
+         *  System.out.println(response.statusCode()); }</pre>
          *
          * @param subscriber the subscriber
          * @return a response body handler
@@ -304,12 +288,10 @@
          * BodySubscriber} and {@code Flow.Subscriber}.
          *
          * <p> For example:
-         * <pre> {@code
-         * TextSubscriber subscriber = ...;  // accumulates bytes and transforms them into a String
-         * HttpResponse<String> response = client.sendAsync(request,
-         *     BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult)).join();
-         * String text = response.body();
-         * }</pre>
+         * <pre> {@code  TextSubscriber subscriber = ...;  // accumulates bytes and transforms them into a String
+         *  HttpResponse<String> response = client.sendAsync(request,
+         *      BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult)).join();
+         *  String text = response.body(); }</pre>
          *
          * @param <S> the type of the Subscriber
          * @param <T> the type of the response body
@@ -345,12 +327,10 @@
          * BodySubscriber} and {@code Flow.Subscriber}.
          *
          * <p> For example:
-         * <pre> {@code
-         *  TextSubscriber subscriber = new TextSubscriber();
+         * <pre> {@code  TextSubscriber subscriber = new TextSubscriber();
          *  HttpResponse<Void> response = client.sendAsync(request,
          *      BodyHandler.fromLineSubscriber(subscriber, "\n")).join();
-         *  System.out.println(response.statusCode());
-         * }</pre>
+         *  System.out.println(response.statusCode()); }</pre>
          *
          * @param subscriber the subscriber
          * @return a response body handler
@@ -381,12 +361,10 @@
          * BodySubscriber} and {@code Flow.Subscriber}.
          *
          * <p> For example:
-         * <pre> {@code
-         * TextSubscriber subscriber = ...;  // accumulates bytes and transforms them into a String
-         * HttpResponse<String> response = client.sendAsync(request,
-         *     BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult, "\n")).join();
-         * String text = response.body();
-         * }</pre>
+         * <pre> {@code  TextSubscriber subscriber = ...;  // accumulates bytes and transforms them into a String
+         *  HttpResponse<String> response = client.sendAsync(request,
+         *      BodyHandler.fromSubscriber(subscriber, TextSubscriber::getTextResult, "\n")).join();
+         *  String text = response.body();  }</pre>
          *
          * @param <S> the type of the Subscriber
          * @param <T> the type of the response body
@@ -749,7 +727,8 @@
     }
 
     /**
-     * A subscriber for response bodies.
+     * A {@code BodySubscriber} consumes response body bytes and converts them
+     * into a higher-level Java type.
      *
      * <p> The object acts as a {@link Flow.Subscriber}&lt;{@link List}&lt;{@link
      * ByteBuffer}&gt;&gt; to the HTTP client implementation, which publishes
@@ -758,27 +737,27 @@
      * is a strictly ordered representation of the response body. Both the Lists
      * and the ByteBuffers, once passed to the subscriber, are no longer used by
      * the HTTP client. The subscriber converts the incoming buffers of data to
-     * some user-defined object type {@code T}.
-     *
-     * <p> The {@link #getBody()} method returns a {@link CompletionStage}{@code
-     * <T>} that provides the response body object. The {@code CompletionStage}
-     * must be obtainable at any time. When it completes depends on the nature
-     * of type {@code T}. In many cases, when {@code T} represents the entire
-     * body after being read then it completes after the body has been read. If
-     * {@code T} is a streaming type such as {@link java.io.InputStream} then it
-     * completes before the body has been read, because the calling code uses it
-     * to consume the data.
+     * some higher-level Java type {@code T}.
      *
-     * @apiNote To ensure that all resources associated with the
-     * corresponding exchange are properly released, an implementation
-     * of {@code BodySubscriber} must ensure to {@linkplain
-     * Flow.Subscription#request request} more data until {@link
-     * #onComplete() onComplete} or {@link #onError(Throwable) onError}
-     * are signalled, or {@linkplain Flow.Subscription#request cancel} its
-     * {@linkplain #onSubscribe(Flow.Subscription) subscription}
-     * if unable or unwilling to do so.
-     * Calling {@code cancel} before exhausting the data may cause
-     * the underlying HTTP connection to be closed and prevent it
+     * <p> The {@link #getBody()} method returns a
+     * {@link CompletionStage}&lt;{@code T}&gt; that provides the response body
+     * object. The {@code CompletionStage} must be obtainable at any time. When
+     * it completes depends on the nature of type {@code T}. In many cases,
+     * when {@code T} represents the entire body after being consumed then
+     * the {@code CompletionStage} completes after the body has been consumed.
+     * If  {@code T} is a streaming type, such as {@link java.io.InputStream
+     * InputStream}, then it completes before the body has been read, because
+     * the calling code uses the {@code InputStream} to consume the data.
+     *
+     * @apiNote To ensure that all resources associated with the corresponding
+     * HTTP exchange are properly released, an implementation of {@code
+     * BodySubscriber} should ensure to {@linkplain Flow.Subscription#request
+     * request} more data until one of {@linkplain #onComplete() onComplete} or
+     * {@link #onError(Throwable) onError} are signalled, or {@linkplain
+     * Flow.Subscription#request cancel} its {@linkplain
+     * #onSubscribe(Flow.Subscription) subscription} if unable or unwilling to
+     * do so. Calling {@code cancel} before exhausting the response body data
+     * may cause the underlying HTTP connection to be closed and prevent it
      * from being reused for subsequent operations.
      *
      * @param <T> the response body type
@@ -790,7 +769,7 @@
          * Returns a {@code CompletionStage} which when completed will return
          * the response body object. This method can be called at any time
          * relative to the other {@link Flow.Subscriber} methods and is invoked
-         * using the client's {@link Executor}.
+         * using the client's {@link HttpClient#executor() executor}.
          *
          * @return a CompletionStage for the response body
          */
@@ -1123,46 +1102,43 @@
          }
 
         /**
-         * Returns a {@code BodySubscriber} whose response body is mapped
-         * using the supplied mapping function from one type {@code <T>} to
-         * another type {@code <U>}. The mapping function is executed
-         * using the {@link Executor} of the sending client and can
-         * therefore be used to map any response body type, including
-         * blocking {@link java.io.InputStream}s as shown in the following
-         * example which uses a well-known JSON parser to convert an {@code InputStream}
-         * into any annotated Java object type.
-         * <p>
-         * <b>Example usage</b>
-         * <p> <pre> {@code
-         * public static <W> BodySubscriber<W> asJSON(Class<W> targetType) {
+         * Returns a {@code BodySubscriber} whose response body value is that of
+         * the result of applying the given function to the body object of the
+         * given {@code upstream} {@code BodySubscriber}.
+         *
+         * <p> The mapping function is executed using the client's {@linkplain
+         * HttpClient#executor()}, and can therefore be used to map any response
+         * body type, including blocking {@linkplain InputStream}, as shown in
+         * the following example which uses a well-known JSON parser to convert
+         * an {@code InputStream} into any annotated Java object type.
+         *
+         * <p>For example:
+         * <pre> {@code  public static <W> BodySubscriber<W> asJSON(Class<W> targetType) {
          *     BodySubscriber<InputStream> upstream = BodySubscriber.asInputStream();
          *
-         *     BodySubscriber<W> downstream = mappedFrom(
+         *     BodySubscriber<W> downstream = mapping(
          *           upstream,
          *           (InputStream is) -> {
          *               try (InputStream stream = is) {
          *                   ObjectMapper objectMapper = new ObjectMapper();
-         *                   W result = objectMapper.readValue(stream, targetType);
-         *                   return result;
+         *                   return objectMapper.readValue(stream, targetType);
          *               } catch (IOException e) {
          *                   throw new UncheckedIOException(e);
          *               }
          *           });
          *    return downstream;
-         * }
-         * }</pre>
+         * } }</pre>
          *
-         * @param <T> the type of the body subscriber to be mapped
+         * @param <T> the upstream both type
          * @param <U> the type of the body subscriber returned
          * @param upstream the body subscriber to be mapped
          * @param mapper the mapping function
          * @return a mapped body subscriber
          */
-        public static <T,U> BodySubscriber<U> mappedFrom(
-                BodySubscriber<T> upstream,
-                Function<T, U> mapper)
+        public static <T,U> BodySubscriber<U> mapping(BodySubscriber<T> upstream,
+                                                      Function<T, U> mapper)
         {
-            return new ResponseSubscribers.MappedSubscriber<T, U>(upstream, mapper);
+            return new ResponseSubscribers.MappingSubscriber<T, U>(upstream, mapper);
         }
     }
 }
--- a/src/java.net.http/share/classes/java/net/http/package-info.java	Wed Feb 07 22:49:25 2018 +0000
+++ b/src/java.net.http/share/classes/java/net/http/package-info.java	Thu Feb 08 20:58:35 2018 +0000
@@ -36,20 +36,20 @@
  *    <li>{@link java.net.http.WebSocket}</li>
  * </ul>
  *
- * <p> The API functions asynchronously (using {@link java.util.concurrent.CompletableFuture})
- * and work is done on the threads supplied by the client's {@link java.util.concurrent.Executor}
- * where practical.
- *
- * <p> {@code HttpClient} also provides a simple synchronous mode, where all
- * work may be done on the calling thread.
+ * <p> Asynchronous tasks and dependent actions of returned {@link
+ * java.util.concurrent.CompletableFuture} instances are executed on the threads
+ * supplied by the client's {@link java.util.concurrent.Executor}, where
+ * practical.
  *
- * <p> {@code CompletableFuture}s returned by this API will throw {@link java.lang.UnsupportedOperationException}
- * for their {@link java.util.concurrent.CompletableFuture#obtrudeValue(Object) obtrudeValue}
- * and {@link java.util.concurrent.CompletableFuture#obtrudeException(Throwable) obtrudeException}
- * methods. Invoking the {@link java.util.concurrent.CompletableFuture#cancel cancel}
- * method on a {@code CompletableFuture} returned by this API will not interrupt
- * the underlying operation, but may be useful to complete, exceptionally,
- * dependent stages that have not already completed.
+ * <p> {@code CompletableFuture}s returned by this API will throw {@link
+ * java.lang.UnsupportedOperationException} for their {@link
+ * java.util.concurrent.CompletableFuture#obtrudeValue(Object) obtrudeValue}
+ * and {@link java.util.concurrent.CompletableFuture#obtrudeException(Throwable)
+ * obtrudeException} methods. Invoking the {@link
+ * java.util.concurrent.CompletableFuture#cancel cancel} method on a {@code
+ * CompletableFuture} returned by this API will not interrupt the underlying
+ * operation, but may be useful to complete, exceptionally, dependent stages
+ * that have not already completed.
  *
  * <p> Unless otherwise stated, {@code null} parameter values will cause methods
  * of all classes in this package to throw {@code NullPointerException}.
--- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java	Wed Feb 07 22:49:25 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java	Thu Feb 08 20:58:35 2018 +0000
@@ -48,8 +48,6 @@
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
 import java.util.concurrent.Flow;
 import java.util.concurrent.Flow.Subscriber;
 import java.util.concurrent.Flow.Subscription;
@@ -475,7 +473,7 @@
     public static BodySubscriber<Stream<String>> createLineStream(Charset charset) {
         Objects.requireNonNull(charset);
         BodySubscriber<InputStream> s = new HttpResponseInputStream();
-        return new MappedSubscriber<InputStream,Stream<String>>(s,
+        return new MappingSubscriber<InputStream,Stream<String>>(s,
             (InputStream stream) -> {
                 return new BufferedReader(new InputStreamReader(stream, charset))
                             .lines().onClose(() -> Utils.close(stream));
@@ -602,29 +600,21 @@
      * of the upstream {@code getBody()} and applies the mapper function to
      * obtain the new {@code CompletionStage} type.
      *
-     * Uses an Executor that must be set externally.
-     *
      * @param <T> the upstream body type
      * @param <U> this subscriber's body type
      */
-    public static class MappedSubscriber<T,U> implements BodySubscriber<U> {
-        final BodySubscriber<T> upstream;
-        final Function<T,U> mapper;
+    public static class MappingSubscriber<T,U> implements BodySubscriber<U> {
+        private final BodySubscriber<T> upstream;
+        private final Function<T,U> mapper;
 
-        /**
-         *
-         * @param upstream
-         * @param mapper
-         */
-        public MappedSubscriber(BodySubscriber<T> upstream, Function<T,U> mapper) {
-            this.upstream = upstream;
-            this.mapper = mapper;
+        public MappingSubscriber(BodySubscriber<T> upstream, Function<T,U> mapper) {
+            this.upstream = Objects.requireNonNull(upstream);
+            this.mapper = Objects.requireNonNull(mapper);
         }
 
         @Override
         public CompletionStage<U> getBody() {
-            return upstream.getBody()
-                    .thenApply(mapper);
+            return upstream.getBody().thenApply(mapper);
         }
 
         @Override
--- a/test/jdk/java/net/httpclient/MappedResponseSubscriber.java	Wed Feb 07 22:49:25 2018 +0000
+++ b/test/jdk/java/net/httpclient/MappedResponseSubscriber.java	Thu Feb 08 20:58:35 2018 +0000
@@ -137,7 +137,7 @@
         @Override
         public BodySubscriber<byte[]> apply(int statusCode, HttpHeaders responseHeaders) {
             assertEquals(statusCode, 200);
-            return HttpResponse.BodySubscriber.mappedFrom(
+            return HttpResponse.BodySubscriber.mapping(
                 new CRSBodySubscriber(), (s) -> s.getBytes()
             );
         }
--- a/test/jdk/java/net/httpclient/SubscriberPublisherAPIExceptions.java	Wed Feb 07 22:49:25 2018 +0000
+++ b/test/jdk/java/net/httpclient/SubscriberPublisherAPIExceptions.java	Thu Feb 08 20:58:35 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
 import java.net.http.HttpRequest.BodyPublisher;
 import java.net.http.HttpResponse.BodyHandler;
 import java.net.http.HttpResponse.BodySubscriber;
+import java.util.function.Function;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 import static java.nio.charset.StandardCharsets.UTF_8;
@@ -130,6 +131,9 @@
         assertThrows(IAE, () -> BodySubscriber.buffering(new NoOpSubscriber(), 0));
         assertThrows(IAE, () -> BodySubscriber.buffering(new NoOpSubscriber(), -1));
         assertThrows(IAE, () -> BodySubscriber.buffering(new NoOpSubscriber(), Integer.MIN_VALUE));
+        assertThrows(NPE, () -> BodySubscriber.mapping(null, Function.identity()));
+        assertThrows(NPE, () -> BodySubscriber.mapping(BodySubscriber.asByteArray(), null));
+        assertThrows(NPE, () -> BodySubscriber.mapping(null, null));
     }
 
     static class NoOpHandler implements BodyHandler<Void> {