Hi Yuji,

On 05/11/16 18:27, KUBOTA Yuji wrote:
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)

Please file an issue for this.

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

This looks ok. I wonder if some of these exceptions could be refactored
into a catch clause with several exception types?

-Chris.


* 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

Reply via email to