Friday, February 21, 2014

Fixing java.net.BindException: Cannot assign requested address: JVM_Bind in Tomcat, Jetty

Some of the most dreaded error in Java based client server based application is networking related error, e.g. java.net.BindException: Cannot assign requested address: JVM_Bind. I have faced this issue, while working with web servers like Tomcat, Jetty, and Weblogic before, but yesterday it came again, when one of my colleague faced this issue in Windows. As soon as Java programmers sees java.net.BindException, they come to conclusion that it's issue with two process listening on same port, and often mistook it for Java.net.BindException: Address already in use: JVM_Bind:8080, which is slightly different than this. If you look Java documentation for java.net.BindExcpetion, you will find this "Signals that an error occurred while attempting to bind a socket to a local address and port. Typically, the port is in use, or the requested local address could not be assigned." It's the second part, which is more interesting in case of java.net.BindException: Cannot assign requested address: JVM_Bind.


How to fix java.net.BindException: Cannot assign requested address: JVM_Bind in Tomcat, JettyWhen you start a web server or application server, which typically listen on a port e.g. Tomcat or Jetty listens on 8080 and 8084 for HTTP and HTTPS traffic, they bind a socket to a local address and port. If you give them hostname e.g. localhost or devhost, then they used /etc/host in both Windows and Linux to resolve domain name into IP address, if this mapping is incorrect than you will get java.net.BindException: Cannot assign requested address: JVM_Bind. This host to IP address mapping file can be found at C:\Windows\System32\Drivers\etc\hosts, where C:\Windows is  where you have installed windows operating system. If you look at this file, you will see it contains IP address and hostname as shown below :

#127.0.0.1 localhost
192.168.52.1 localhost

If this mapping is changed and localhost cannot be resolve to 192.168.52.1 then you will get java.net.BindException: Cannot assign requested address: JVM_Bind. You can try by following program to reproduce this issue, remember, you need admin rights to change /etc/host settings in Windows.

import java.io.IOException;
import java.net.ServerSocket;

public class ServerSocketTesting {

    public static void main(String args[]) throws IOException {

        ServerSocket server = new ServerSocket(8080);
        System.out.println("Server is started, listening connections on port :8080 ");
        server.accept();
    }
}

If your /etc/host mapping is incorrect than you will see something like

Exception in thread "main" java.net.BindException: Cannot assign requested address: JVM_Bind
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:383)
    at java.net.ServerSocket.bind(ServerSocket.java:328)
    at java.net.ServerSocket.(ServerSocket.java:194)
    at java.net.ServerSocket.(ServerSocket.java:106)



Just, correct the mapping, or add 127.0.0.1 against localhost to resolve this issue.  That's all about how to fix java.net.BindException: Cannot assign requested address: JVM_Bind error in Java based client server application e.g. Minecraft, a popular game in Java, which also communicate with server and other machines using TCP and sockets. It could  also be occur when you are using web and application server like Tomcat, Jetty or Weblogic as well. Next time, instead of thinking that two process is listening on same port, also think about hostname to IP address resolution issue and verify contents of /etc/host file in both windows and Linux. Let me know if you are facing this issue and not able to resolve, pasting error message and what you are trying to do will help to solve your error quickly and accurately.

How to resolve java.net.BindException: Cannot assign requested address: JVM_Bind in Tomcat

If you are getting this issue in Tomcat web server than open your server.xml, which contains host and port information for Tomcat connectors. You can find server.xml in location (Windows OS) C:\Program Files\Apache Software Foundation\Apache Tomcat 7.0.41\conf\server.xml. Now look for your connector, if you are using default settings then your connector will look like this :

 <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

but if you have modified it to include address="TestServer", then look for TestServer mapping in /etc/hosts file. Try ping with the IP address and see if it up or not, you will find that it's incorrect. Just update with right IP and restart Tomcat.

Similarly, you can resolve java.net.BindException: Cannot assign requested address: JVM_Bind in Jetty or any other web server. Key thing is not to confuse this error with address already in use error.

All the best and let me know if you face similar issues.

3 comments :

Anonymous said...

Hello there I am getting below exception, while running QuickFIXJ based FIX engine :

Caused by: java.net.BindException: Cannot assign requested address
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:444)
at sun.nio.ch.Net.bind(Net.java:436)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.mina.transport.socket.nio.SocketAcceptor.registerNew(SocketAcceptor.java:363)
at org.apache.mina.transport.socket.nio.SocketAcceptor.access$800(SocketAcceptor.java:55)
at org.apache.mina.transport.socket.nio.SocketAcceptor$Worker.run(SocketAcceptor.java:222)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:724)

It runs fine on my desktop but as soon as I try to run it on Linux, it gives me this exception, I have already check no other instance of program is running and no other process is using this port.

SARAL SAXENA said...

@Anonymous ..Most likely related to another process using port . On Windows, run the command:

netstat -a -n | find "LIST"

And it should list anything there that's hogging the port. Of course you'll then have to go and manually kill those programs in Task Manager. If this still doesn't work, replace the line:

serverSocket = new ServerSocket(9999);

With:

InetAddress locIP = InetAddress.getByName("192.168.1.20");
serverSocket = new ServerSocket(9999, 0, locIP);

Of course replace 192.168.1.20 with your actual IP address, or use 127.0.0.1.

Pascal said...

-Djava.net.preferIPv4Stack=true could also help (if worked for me adding this to my tomcat settings)

Post a Comment