RMI Server (seems to) ignore connections over WAN
<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>