Question

I have a Java class for use with JUnit 4.x. Within each @Test method I create a new HttpServer, with port 9090 used. The first invocation works find, but subsequent ones error with "Address is already in use: bind".

Here's an example:

@Test
public void testSendNoDataHasValidResponse() throws Exception {
    InetSocketAddress address = new InetSocketAddress(9090);
    HttpHandler handler = new HttpHandler() {

        @Override
        public void handle(HttpExchange exchange) throws IOException {
            byte[] response = "Hello, world".getBytes();
            exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
            exchange.getResponseBody().write(response);
            exchange.close();
        }
    };
    HttpServer server = HttpServer.create(address, 1);
    server.createContext("/me.html", handler);
    server.start();

    Client client = new Client.Builder(new URL("http://localhost:9090/me.html"), 20, "mykey").build();

    client.sync();
    server.stop(1);
    assertEquals(true, client.isSuccessfullySynchronized());
}

Clearly the HttpServer is held solely within each method and is stopped before the end. I fail to see what's continuing to hold any sockets open. The first test passes, subsequent ones fail every time.

Any ideas?

EDIT with corrected method:

@Test
public void testSendNoDataHasValidResponse() throws Exception {
    server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 1);
    HttpHandler handler = new HttpHandler() {

        @Override
        public void handle(HttpExchange exchange) throws IOException {
            byte[] response = "Hello, world".getBytes();
            exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
            exchange.getResponseBody().write(response);
            exchange.close();
        }
    };
    server.createContext("/me.html", handler);
    server.start();
    InetSocketAddress address = server.getAddress();
    String target = String.format("http://%s:%s/me.html", address.getHostName(), address.getPort());

    Client client = new Client.Builder(new URL(target), 20, "mykey").build();

    client.sync();
    server.stop(0);
    assertEquals(true, client.isSuccessfullySynchronized());
}
Was it helpful?

Solution

There is usually a 2 minute wait time before you can rebind to a specific port number. Run netstat to confirm if your server's connection is in TIME_WAIT. If so, you can get around it by using the SO_REUSEADDR option before binding. Docs are here for java.

OTHER TIPS

jello's answer is on the money.

Other workarounds:

When you create HttpServer, you specified

the maximum number of queued incoming connections to allow on the listening socket

which is 1

server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 1);

link

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top