Note that there are some explanatory texts on larger screens.

plurals
  1. PO1s Delay in HttpServer since Java 7
    primarykey
    data
    text
    <p>We are using the internal <code>HttpServer</code> class in a project to exchange data between a client and a server over HTTP. As we switched to Java 7, we realized a delay in the delivery of the results. We could reduce the problem to the following sample:</p> <p>Class <code>EchoServer</code> creates the context <code>/echo</code> which simply returns the current date and the request URI upon each request. This service is then invoked by a client in a loop.</p> <pre><code>import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import java.util.Date; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class EchoServer { public static void main(String[] args) throws IOException { HttpServer server = HttpServer.create(new InetSocketAddress(80), 0); server.createContext("/echo", new EchoHandler()); server.start(); } static class EchoHandler implements HttpHandler { public void handle(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add("Content-type", "text/html"); String response = "&lt;b&gt;" + new Date() + "&lt;/b&gt; for " + httpExchange.getRequestURI(); httpExchange.sendResponseHeaders(200, response.length()); OutputStream os = httpExchange.getResponseBody(); os.write(response.getBytes()); os.close(); } } } </code></pre> <p>The following client invokes the service in an infinite loop using class <code>URL</code> and prints the first character from the returned stream (which will be the <code>&lt;</code> sign). In addition, the client prints the current time.</p> <pre><code>import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; public class EchoClient { public static void main(String[] args) throws Exception{ while(true) { URL url = new URL("http://localhost:80/echo"); BufferedReader rd = new BufferedReader(new InputStreamReader(url.openStream())); int res = rd.read(); System.out.println((char)res); System.out.println(System.currentTimeMillis()); } } } </code></pre> <p>If this code is executed on Java6, everything works fine and a result is printed approx. every 5 ms.</p> <pre><code>% java -version java version "1.6.0_24" Java(TM) SE Runtime Environment (build 1.6.0_24-b07) Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode) % java EchoClient &lt; 1362515635677 &lt; 1362515635682 &lt; 1362515635687 &lt; 1362515635691 </code></pre> <p>If the code is executed on Java7, then each request uses 1000ms approx.</p> <pre><code>% java -version java version "1.7.0_17" Java(TM) SE Runtime Environment (build 1.7.0_17-b02) Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode) % java EchoClient &lt; 1362517297845 &lt; 1362517298844 &lt; 1362517299845 &lt; 1362517300845 </code></pre> <p>It seems that a timeout of 1000ms is hidden somewhere. If the character is read on the <code>InputStreamReader</code> instead over the <code>BufferedReader</code>, the same delay happens. If a byte is read from the input stream directly, then no delay can be seen. On the other hand, if the <code>EchoClient</code> program is run against a servlet, then everything works fine, independent of whether the <code>BufferedReader</code> or the <code>InputStreamReader</code> is used.</p> <p>It seems, that class <code>InputStreamReader</code> is expecting something from the server which is no longer delivered by the Java 7 implementation of HttpServer. Do you have an idea what exactly happens here and how this problem could be resolved? A workaround? Or is this a bug?</p> <p>Thanks!</p> <hr> <p>I have added further timings to the client code:</p> <pre><code>public static void main(String[] args) throws Exception{ while(true) { System.out.println("0: "+System.currentTimeMillis()); URL url = new URL("http://localhost:80/echo"); System.out.println("1: "+System.currentTimeMillis()); InputStream in = url.openStream(); System.out.println("2: "+System.currentTimeMillis()); InputStreamReader isr = new InputStreamReader(in); System.out.println("3: "+System.currentTimeMillis()); char res = (char)isr.read(); // character read is `&lt;` System.out.println(res + ": "+System.currentTimeMillis()); } } </code></pre> <p>with the following result:</p> <pre><code>% java EchoClient 0: 1362532555535 1: 1362532555537 2: 1362532555608 3: 1362532555609 &lt;: 1362532555611 0: 1362532555612 1: 1362532555613 2: 1362532556608 3: 1362532556609 &lt;: 1362532556610 0: 1362532556611 1: 1362532556612 2: 1362532557609 3: 1362532557610 &lt;: 1362532557611 0: 1362532557612 1: 1362532557613 </code></pre> <p>The first invocation of <code>openStream</code> takes some time (70ms), but all further invocations of <code>openStream</code> take much longer (996ms approx).</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload