title: "java.rmi.ConnectException: Connection refused to host" when exporting an object client-side
body: <p>I'm stuck with that for at least 5 hours now and have no other resort but to ask here. I'm writing an RMI application. I'd like the server to bind a remote object (<code>NoteBoardImpl</code> here), that will be looked-up by the client. Client passes its listener (<code>NoteBoardListener</code> here) to the server, the listener is also a remote object exported by the client. </p>
  
  <p>I've prepared a simple SSCCE here, so I really hope somebody can look into it. All the classes are in the same folder the default package. I know it's discouraged and I should've split the application in three jars, but I wanted to keep it as simple as possible here.</p>
  
  <p><em>Remote interfaces:</em></p>
  
  <pre><code>import java.rmi.Remote;
  import java.rmi.RemoteException;
  
  public interface INoteBoard extends Remote {
      public void test(INoteBoardListener listener) throws RemoteException;
  }
  </code></pre>
  
  <p><br></p>
  
  <pre><code>import java.rmi.Remote;
  import java.rmi.RemoteException;
  
  public interface INoteBoardListener extends Remote {
      public void onNewText(String text) throws RemoteException;
  }
  </code></pre>
  
  <p><em>Interfaces implementations:</em></p>
  
  <pre><code>import java.rmi.RemoteException;
  
  public class NoteBoardImpl implements INoteBoard {
      @Override
      public void test(INoteBoardListener listener) throws RemoteException {
          listener.onNewText("server call the listener");
      }
  }
  </code></pre>
  
  <p><br></p>
  
  <pre><code>import java.rmi.RemoteException;
  
  public class NoteBoardListener implements INoteBoardListener {
      @Override
      public void onNewText(String text) throws RemoteException {
          System.out.println(text);
      }
  }
  </code></pre>
  
  <p><em>Client and server:</em></p>
  
  <pre><code>import java.rmi.Naming;
  import java.rmi.server.UnicastRemoteObject;
  
  public class Client {
      public static void main(String[] args) {
          if (args.length &lt; 2) {
              System.out.println("2 arguments required:\nRMI_IP RMI_port");
              return;
          }
          System.setProperty("java.rmi.server.hostname", args[0]);
          try {
              INoteBoard nb = (INoteBoard) Naming.lookup(String.format("rmi://%s:%s/note", args[0], args[1]));
              INoteBoardListener l = (INoteBoardListener) UnicastRemoteObject.exportObject(new NoteBoardListener(), 0);
              nb.test(l);
              l.onNewText("client invokes listener");
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p><br></p>
  
  <pre><code>import java.rmi.Naming;
  import java.rmi.server.UnicastRemoteObject;
  
  public class Server {
      public static void main(String[] args) {
          if (args.length &lt; 2) {
              System.out.println("2 arguments required:\nRMI_IP RMI_port");
              return;
          }
          System.setProperty("java.rmi.server.hostname", args[0]);
          try {
              INoteBoard noteBoard = (INoteBoard) UnicastRemoteObject.exportObject(new NoteBoardImpl(), 0);
              Naming.rebind(String.format("rmi://%s:%s/note", args[0], args[1]), noteBoard);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>I've tried to simulate a distributed system for testing purposes and ran the client on a virtual machine. The host-VM network has the following specs - host IP = 192.168.56.1, VM IP = 192.168.56.101.<br>
  First I ran the client and the server locally, using the following commands (having started <code>rmiregistry 1099</code> beforehand). The working directory is the project's root and the compiled classes are in <code>bin</code> directory:<br>
  <code>java -cp bin -Djava.rmi.server.codebase=http://student.agh.edu.pl/~grajewsk/bin/ Server 192.168.56.1 1099</code><br>
  <code>java -cp bin Client 192.168.56.1 1099</code><br>
  And it worked.</p>
  
  <p>Then I ran the client program on the VM using the same command and here's the exception I got:</p>
  
  <pre><code>java.rmi.ConnectException: Connection refused to host: 192.168.56.1; nested exception is: 
      java.net.ConnectException: Connection refused
      at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
      at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
      at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
      at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:128)
      at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
      at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
      at sun.proxy.$Proxy0.test(Unknown Source)
      at Client.main(Client.java:14)
  Caused by: java.net.ConnectException: Connection refused
      at java.net.PlainSocketImpl.socketConnect(Native Method)
      at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:327)
      at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:193)
      at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
      at java.net.Socket.connect(Socket.java:546)
      at java.net.Socket.connect(Socket.java:495)
      at java.net.Socket.&lt;init&gt;(Socket.java:392)
      at java.net.Socket.&lt;init&gt;(Socket.java:206)
      at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
      at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:146)
      at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
      ... 7 more
  </code></pre>
  
  <p>Notice how the object is successfully looked-up in the server's registry, then the client-side remote object is exported (also with success) and the execution breaks in the 14-th line, where I'm trying to invoke a method on the server-side object passing the client-side object.</p>
  
  <p>I have no firewalls on either of the systems, pings in both directions go flawlessly. I know that there must be some conceptual problem here and certainly I misunderstood something about the RMI. I'd very much appreciate your help.</p>
  
  <p>The binary codebase is <a href="http://student.agh.edu.pl/~grajewsk/bin/" rel="nofollow">on my student's server</a>, as well as <a href="http://student.agh.edu.pl/~grajewsk/src/" rel="nofollow">the source code</a>. Thank you in advance!</p>