JDK-6675392 : Selector leak in com.sun.net.httpserver.SelectorCache
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 6
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2008-03-14
  • Updated: 2011-02-16
Description
FULL PRODUCT VERSION :
java version "1.6.0_04"
Java(TM) SE Runtime Environment (build 1.6.0_04-b12)
Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
The freeSelector(Selector selector) method of com.sun.net.httpserver.SelectorCache is never called when bad requests are reject. (request send via a telnet console for exemple)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
To reproduce the bug, it's simple, you just need to open a telnet session to the httpServer, writes random bytes and then press Enter.
The process handle count will increase until the system limit

The step to run the test case :
1 - start the server
2 - start the badClient

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The correct behavior is that the handler count decrease to the minimal value
after the 20 min (because the system property
"sun.net.httpserver.selCacheTimeout" is set to 20;

ACTUAL -
You will see that the handler count of the server will increase, but never
decrease, event if you wait a long time after the end off the client.

---------- BEGIN SOURCE ----------

Here is the code of the Server side :

-----------------------------------------
import java.io.*;
import java.net.*;

import com.sun.net.httpserver.*;

public class SimpleServer implements HttpHandler
{
	public static void main(String[] args)
	{
		try
		{
			System.setProperty("sun.net.httpserver.selCacheTimeout", "20");

			HttpServer server = HttpServer.create(new InetSocketAddress(8080), 1);
			server.createContext("/", new SimpleServer());
			server.setExecutor(null);
			server.start();
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}

	public void handle(HttpExchange t) throws IOException
	{
		InputStream is = t.getRequestBody();
		byte[] bBody = new byte[1000];
		is.read(bBody);
		String response = "Hello\n";
		t.sendResponseHeaders(200, response.length());
		OutputStream os = t.getResponseBody();
		os.write(response.getBytes());
		is.close();
		os.close();
		t.close();
	}
}
-----------------------------------------

And now, the code of a client which sends bag request :

-----------------------------------------
import java.io.*;
import java.net.*;

public class BadClient
{
	private static int		sleepTime	= 5000;
	private static String	addr		= "127.0.0.1";
	private static int		port		= 8080;

	public static void main(String[] args)
	{
		Socket socket;
		InetSocketAddress serverAddr = new InetSocketAddress(addr, port);
		byte[] badRequest = "bad request\r\n".getBytes();
		try
		{
			while(true)
			{
				socket = new Socket();
				socket.connect(serverAddr);
				OutputStream out = socket.getOutputStream();
				out.write(badRequest);
				Thread.sleep(sleepTime);
				socket.close();
			}
		}
		catch(Throwable t)
		{
			t.printStackTrace();
		}
	}
}

---------- END SOURCE ----------


REPRODUCIBILITY :
This bug can be reproduced always.