United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-7179799 : No BindException when another program is using the port

Details
Type:
Bug
Submit Date:
2012-06-26
Status:
Resolved
Updated Date:
2013-06-20
Project Name:
JDK
Resolved Date:
2013-06-20
Component:
core-libs
OS:
windows_2008,windows_7
Sub-Component:
java.net
CPU:
x86,generic
Priority:
P3
Resolution:
Duplicate
Affected Versions:
6u32,7,7u5
Fixed Versions:
8

Related Reports
Duplicate:
Duplicate:
Duplicate:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601] (Windows 7 Enterprise 64-bit SP1)

A DESCRIPTION OF THE PROBLEM :
When a port is bind to a ServerSocket with setReuseAddress(false), the address(port) is still free to be used, i.e. the call to setReuseAddress(false) is not effective.

REGRESSION.  Last worked in version Java 1.6.0 update 31

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Run the executable compiled from the attached source code.
2) Run the executable again without killing the first one.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The first run of the executable should be successful and give HTTP response normally.
The second run of the executable should be fail with exception thrown, like:
Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind

This expected result can be produced by the same executable under Java 1.6.0 update 31, but not Java 1.7.0 update 5.
ACTUAL -
The result of the first run of the executable is as expected.
The second run of the executable is unexpectedly successfully. No exception is thrown. By check with the command: netstat -aon | find /i "listening" | find "8080", both run of the executable is listening to 0.0.0.0:8080 but only the first run is giving HTTP response.
The second run gave HTTP response after the first run was killed.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class TestServerSocket {
    private static final String HEADER = "HTTP/1.1 200 OK\r\n" + "Content-type: text/html\r\n"
            + "Connection: close\r\n" + "\r\n";
    
    private static final int PORT = 8080;
    
    private static void exit(int status) {
        try {
            System.in.read();
        } catch (IOException e) {
        }
        System.exit(status);
    }
    
    private static void handle(Socket socket) {
        System.out.println(socket.getInetAddress() + ":" + socket.getPort());
        StringBuilder buffer = new StringBuilder();
        buffer.append(HEADER);
        buffer.append(TestServerSocket.class.getClassLoader());
        try {
            socket.getOutputStream().write(buffer.toString().getBytes());
        } catch (IOException e) {
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
            }
        }
        
    }
    
    public static void main(String[] args) throws IOException {
        int port;
        
        try {
            port = Integer.parseInt(args[0]);
        } catch (Exception e) {
            port = PORT;
        }
        
        final ServerSocket server = new ServerSocket();
        server.setReuseAddress(false);
        server.bind(new InetSocketAddress(port));
        
        // Terminator thread
        new Thread() {
            public void run() {
                try {
                    while (System.in.read() != 4);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    server.close();
                } catch (IOException e) {
                }
                exit(0);
            }
        }.start();
        
        System.out.println("Listening on: " + port);
        Socket client = null;
        while (true) {
            try {
                client = server.accept();
                handle(client);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

---------- END SOURCE ----------
Team wants clarification on this issue.

                                    

Comments
EVALUATION

JDK7 uses the new Windows IPv6 stack which has separate port spaces for IPv4 and IPv6. The issue can be worked around by running with IPv6 disabled (-Djava.net.preferIPv4Stack=true).
                                     
2012-07-14



Hardware and Software, Engineered to Work Together