Hi all, com.sun.net.httpserver in jdk9 does not catch RejectedExecutionException and it does not close connections. We must catch this exception to close a socket.
Please review the following patch and reproduce steps. If you agree with that this is an issue of jdk9, I create a new issue on JBS. (I'm author) * patch diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java @@ -442,10 +442,13 @@ logger.log (Level.TRACE, "Dispatcher (4)", e1); closeConnection(conn); } catch (IOException e) { logger.log (Level.TRACE, "Dispatcher (5)", e); closeConnection(conn); + } catch (RejectedExecutionException e) { + logger.log (Level.TRACE, "Dispatcher (9)", e); + closeConnection(conn); } } } _ static boolean debug = ServerConfig.debugEnabled (); * steps to reproduce 1. java -Djava.util.logging.config.file=logging.properties SmallHttpServer 2. post tcp connections by curl or other ways e.g.: while true; do curl -XPOST --noproxy 127.0.0.1 http://127.0.0.1:8080/; done 3. wait RejectedExecutionException occurs as below and then SmallHttpServer stops by this issue. ---- Nov 05, 2016 12:01:48 PM sun.net.httpserver.ServerImpl$Dispatcher run FINER: Dispatcher (7) java.util.concurrent.RejectedExecutionException: Task sun.net.httpserver.ServerImpl$Exchange@37b50d9e rejected from java.util.concurrent.ThreadPoolExecutor@1b3178d4[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 7168] at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(java.base/ThreadPoolExecutor.java:2076) at java.util.concurrent.ThreadPoolExecutor.reject(java.base/ThreadPoolExecutor.java:842) at java.util.concurrent.ThreadPoolExecutor.execute(java.base/ThreadPoolExecutor.java:1388) at sun.net.httpserver.ServerImpl$Dispatcher.handle(jdk.httpserver/ServerImpl.java:440) at sun.net.httpserver.ServerImpl$Dispatcher.run(jdk.httpserver/ServerImpl.java:405) at java.lang.Thread.run(java.base/Thread.java:844) (SmallHttpServer is stopping by not closing socket) ---- *logging.properties handlers = java.util.logging.ConsoleHandler com.sun.net.httpserver.level = FINEST java.util.logging.ConsoleHandler.level = FINEST java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter * SmallHttpServer.java import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import java.net.InetSocketAddress; import java.util.Scanner; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class SmallHttpServer { public static void main(String[] args) throws Exception { int POOL_SIZE = 1; String HOST = args.length < 1 ? "127.0.0.1" : args[0]; int PORT = args.length < 2 ? 8080 : Integer.valueOf(args[1]); // Setup a minimum thread pool to rise RejectExecutionException in httpserver ThreadPoolExecutor miniHttpPoolExecutor = new ThreadPoolExecutor(POOL_SIZE, POOL_SIZE, 0L, TimeUnit.MICROSECONDS, new LinkedBlockingQueue<>(1), (Runnable r) -> { return new Thread(r); }); HttpServer httpServer = HttpServer.create(new InetSocketAddress(HOST, PORT), 0); httpServer.setExecutor(miniHttpPoolExecutor); HttpHandler res200handler = (HttpExchange exchange) -> { exchange.sendResponseHeaders(200, 0); exchange.close(); }; httpServer.createContext("/", res200handler); httpServer.start(); // Wait stdin to exit Scanner in = new Scanner(System.in); while (in.hasNext()) { System.out.println(in.nextLine()); } httpServer.stop(0); miniHttpPoolExecutor.shutdownNow(); } } Thanks, Yuji