Hello,

I'm working on an application that uses a ServerSocket, but it (at points) stops the server thread and restarts it, throwing a java.net.BindException: address already in use exception.

How can I unbind the ServerSocket (.close() is not working to unbind) so I can re-use the same port seconds later?

Note: The thread the ServerSocket is in is redefined when I reload it.

-- Turt2Live

Dani AI

Generated

A few practical points for the “address already in use” problem when restarting a Java ServerSocket. Common causes are: the TCP port still being held in an OS socket state (TIME_WAIT or similar), the ServerSocket not being closed cleanly, or a resource/classloader leak that keeps the JVM holding the socket. As discovered, a stuck classloader is a real culprit in hot‑reload scenarios. ’s idea to connect and unblock accept() is a valid shutdown trick, but it won’t help if the JVM still has references to the socket.

Recommended checklist and safe patterns:

  • Create and bind with reuse set before binding. Calling setReuseAddress(true) after a bind is too late.
  • Ensure the accept thread exits after close() (accept will throw and the thread can terminate). Join the thread before creating a new ServerSocket.
  • Always close sockets in a finally block and shut down any executor services or non‑daemon threads started by the reloaded code.
    Example pattern:
    ServerSocket ss = new ServerSocket();
    ss.setReuseAddress(true);
    ss.bind(new InetSocketAddress(port));
    try {
    while (running) {
      Socket s = ss.accept();
      ...
    }
    } finally {
    ss.close();
    }

    Shutdown sequence:

    running = false;
    ss.close();      // causes accept() to throw
    serverThread.join();

Quick diagnostic commands to find who holds the port:

# Linux/macOS
lsof -i :<port>
ss -ltnp | grep <port>

# Windows (cmd)
netstat -ano | findstr :<port>
tasklist /fi "PID eq <pid>"

Notes and cautions: SO_REUSEADDR semantics vary by OS and won’t override a truly active listener in another process. In classloader/reload setups, ensure no static fields, thread locals, shutdown hooks, MBeans, or background threads retain references — those prevent the classloader (and its sockets) from being garbage collected. In many cases the simplest fix is to stop the old server thread and free all resources, or run the server in a separate process so full restarts truly release the port.

Recommended Answers

All 5 Replies

An idea: Connect to the socket so the accept method returns and then have the code exit the thread.

An idea: Connect to the socket so the accept method returns and then have the code exit the thread.

I do that, it's just the way the superclass handles (not mine) my code. The classloader loads, runs the code, then on command unloads and reloads the code. The JVM however seems to be holding onto the bind :/

Can you make a small simple program that compiles, executes and shows the problem (a SSCCE)?

Do you close the socket?

Can you make a small simple program that compiles, executes and shows the problem (a SSCCE)?

Do you close the socket?

While creating this, I found my problem :P

The classloader was not properly unloading the class.

(Bad code on their fault :P)

Sometimes its more easier to do a prototype as NormR1 said.
Nice you got it fix

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.