At first glance this may seem like a basic networking issue - but I think that is not the case. It seems like Java itself is "ignoring" the RMI connection.
All Java 8u101 on Windows 10 PCs.
We have a quite mature and robust distributed Java application that communicates via RMI on a LAN.
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).
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.
It seems that all the networking itself is OK as follows ....
- on the LAN everything runs perfectly as normal
- Non RMI is OK:
- 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)
- RMI port seem OK from the client end
- using telnet client at the remote location we can establish a connection to the RMI port
- RMI port seems to connect at the server PC:
- 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.
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.
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.
Can anyone offer any clues on this?
- any way to verify that the connection gets to Java?
- might it be a Java security that is blocking this before it passes on to RMI server?
Any suggestions or guidance would be most appreciated.
(Edited, adding more details ...)
A little more information is as follows ...
- within the LAN the server PC is known as 192.168.0.110
- from the remote location (via the WAN) the server PC is known as 110.142.83.167
- the remote client seems to get the RMI server object
- The stack trace (detailed below) has "Connection refused to host: 192.168.0.110;"
- 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
The stack traces are as follows ...
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<<
StackTraceLogger ------ Throwable.MSG=Connection refused to host: 192.168.0.110; nested exception is:
java.net.ConnectException: Connection timed out: connect< 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)
Following super cut down version (no boiler plate etc) of the code ...
At RMI server ...
// 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);
}
}
ServerRMIObject ...
public final class ServerRMIObject extends java.rmi.server.UnicastRemoteObject {
private List<ClientRMIObject> 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);
}
}
}
At each RMI client ...
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);
}
}