title: RMI Server (seems to) ignore connections over WAN
body: <p>At first glance this may seem like a basic networking issue - but I <strong><em>think</em></strong> that is not the case. It seems like Java itself is "ignoring" the RMI connection.</p>
  
  <p>All Java 8u101 on Windows 10 PCs.</p>
  
  <p>We have a quite mature and robust distributed Java application that communicates via RMI on a LAN.<br>
  There has been no problem at all for our customers who have run our application on their LANs for many years. 
  This same application also connects to a shared database (on the same "server" PC as the RMI server). </p>
  
  <p>One of our customers has recently established a new building maybe 100 metres away, and their two premises are connected over a WAN. However the Java clients at the remote site cannot connect to the Java RMI server.</p>
  
  <p>It seems that all the networking itself is OK as follows ....</p>
  
  <ul>
  <li>on the LAN everything runs perfectly as normal</li>
  <li>Non RMI is OK: 
  
  <ul>
  <li>from the remote location we can run a different database client and successfully connect to the Database Server (on the same PC as the RMI server)</li>
  </ul></li>
  <li>RMI port seem OK from the client end
  
  <ul>
  <li>using telnet client at the remote location we can establish a connection to the RMI port</li>
  </ul></li>
  <li>RMI port seems to connect at the server PC: 
  
  <ul>
  <li>on the PC that runs the Java RMI server itself we can witness the connections via "netstat -an" which show the established connection arriving from the appropriate WAN IP address.</li>
  </ul></li>
  </ul>
  
  <p>This indicated (to me) that the connection is getting to the correct location and is not being blocked by misconfiguration or a firewall or anything. It seems to get "in" to the RMI server PC, but then does not get to the RMI server itself.</p>
  
  <p>My first guess was to try to use something like "Java Control Panel" and perhaps adjust a security setting that might be restricting RMI traffic - but I can't recognise any such switch.</p>
  
  <p>Can anyone offer any clues on this?</p>
  
  <ul>
  <li>any way to verify that the connection gets to Java?</li>
  <li>might it be a Java security that is blocking this before it passes on to RMI server?</li>
  </ul>
  
  <p>Any suggestions or guidance would be most appreciated.</p>
  
  <p>(Edited, adding more details ...)</p>
  
  <p>A little more information is as follows ...</p>
  
  <ul>
  <li>within the LAN the server PC is known as 192.168.0.110</li>
  <li>from the remote location (via the WAN) the server PC is known as 110.142.83.167</li>
  <li>the remote client seems to get the RMI server object</li>
  <li>The stack trace (detailed below) has "Connection refused to host: 192.168.0.110;"</li>
  <li>so there seems to be confusion as to which IP address it is. The client asked for 110.142.83.167, but the server thinks it is 192.168.0.110</li>
  </ul>
  
  <p>The stack traces are as follows ...</p>
  
  <pre><code>2016-10-18 15:02:11,123 [S38P4][43983  ][AWT-EventQueue-0] WARN  StackTraceLogger log: StackTraceLogger ------- INFO=ClientRMIObject.connectToSentry(): RemoteException: sentryIP=110.142.83.167&lt;&lt;
  StackTraceLogger ------ Throwable.MSG=Connection refused to host: 192.168.0.110; nested exception is: 
      java.net.ConnectException: Connection timed out: connect&lt; Throwable=java.rmi.ConnectException: Connection refused to host: 192.168.0.110; nested exception is: 
      java.net.ConnectException: Connection timed out: connect
  StackTraceLogger.START TRACE .................................
     sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
     sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
     sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
     sun.rmi.server.UnicastRef.invoke(Unknown Source)
     java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
     java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
     com.sun.proxy.$Proxy13.registerWithSentry(Unknown Source)
     com.my.co.package.ClientRMIObject.connectToSentry(ClientRMIObject.java:198)
  </code></pre>
  
  <p>Following super cut down version (no boiler plate etc) of the code ...</p>
  
  <p>At RMI server ...</p>
  
  <pre><code>// auto called at server on startup ...
  public final class MyServer {
    public final static int SRVR_PORT = 21099;
    public final static String LOOKUP_NAME = "MyLookupName";
    public MyServer() {
        java.rmi.registry.Registry reg = java.rmi.registry.LocateRegistry.createRegistry(SRVR_PORT);
        ServerRMIObject srvrRmiObj = new ServerRMIObject();
        reg.rebind(LOOKUP_NAME, srvrRmiObj);
    }
  }
  </code></pre>
  
  <p>ServerRMIObject ...</p>
  
  <pre><code>public final class ServerRMIObject extends java.rmi.server.UnicastRemoteObject {
    private List&lt;ClientRMIObject&gt; clients = ...
  
    public ServerRMIObject() throws java.rmi.RemoteException {
      super(MyServer.SRVR_PORT);
    }
  
    public void registerWithSrvr(ClientRMIObject client) {
      logger.info("This line is never run when called from remote location");
      clients.add(client);
    }
  
    // example method ...
    public void broadcastToClients(Delivery d) {
      for (ClientRMIObject client : clients) {
        client.receiveFromSrvr(d);
      }
    }
  }
  </code></pre>
  
  <p>At each RMI client ...</p>
  
  <pre><code>public final class ClientRMIObject extends java.rmi.server.UnicastRemoteObject {
  
    private final int CLIENT_PORT = 21099;
    private final String SRVR_FROM_LAN = "//192.168.0.110:"+MyServer.SRVR_PORT+"/"+MyServer.LOOKUP_NAME; 
    private final String SRVR_FROM_WAN = "//110.142.83.167:"+MyServer.SRVR_PORT+"/"+MyServer.LOOKUP_NAME;
    private ServerRMIObject rmiSrvr = null;
  
    public ClientRMIObject() {
      super(CLIENT_PORT);
    }
  
    // auto called at client on startup
    public void start() {
      if (VIA_LAN) {
          rmiSrvr = java.rmi.Naming.lookup(SRVR_FROM_LAN);
      } else if (VIA_WAN) {
          rmiSrvr = java.rmi.Naming.lookup(SRVR_FROM_WAN);
      }
  
      // this has been successful to here. 
  
      // the following throws an exception ...
      // java.rmi.ConnectException: Connection refused to host: 192.168.0.110; 
      // please see more exception details above        
      rmiSrvr.registerWithSrvr(this); 
  
    }
  
    // example method ...
    public void receiveFromSrvr(Delivery d) {
       ....
    }
  
    // example broadcast from one client to all clients ...
    public void broadcastToClients(Delivery d) {
      rmiSrvr.broadcastToClients(d);
    }
  }
  </code></pre>