一見、これは基本的なネットワークの問題のように思えるかもしれませんが、そうではないと思います。Java 自体が RMI 接続を「無視」しているようです。
Windows 10 PC 上のすべての Java 8u101。
LAN 上の RMI を介して通信する、非常に成熟した堅牢な分散 Java アプリケーションがあります。
長年にわたり LAN 上で当社のアプリケーションを実行してきたお客様にとって、まったく問題はありませんでした。この同じアプリケーションは、(RMI サーバーと同じ「サーバー」PC 上の) 共有データベースにも接続します。
私たちの顧客の 1 人は最近、おそらく 100 メートル離れた場所に新しい建物を建設し、その 2 つの施設は WAN を介して接続されています。ただし、リモート サイトの Java クライアントは Java RMI サーバーに接続できません。
以下のように、ネットワーキング自体はすべてOKのようです....
- LAN では、すべてが通常どおり完全に実行されます
- 非 RMI は問題ありません:
- リモートの場所から別のデータベース クライアントを実行し、(RMI サーバーと同じ PC 上で) データベース サーバーに正常に接続できます。
- RMI ポートは、クライアント エンドからは正常に見えます
- リモート ロケーションで telnet クライアントを使用して、RMI ポートへの接続を確立できます。
- RMI ポートはサーバー PC で接続されているようです。
- Java RMI サーバー自体を実行している PC では、「netstat -an」を介して接続を監視できます。これは、適切な WAN IP アドレスから到達する確立された接続を示します。
これは、接続が正しい場所に到達しており、構成の誤りやファイアウォールなどによってブロックされていないことを (私には) 示しています。RMI サーバー PC に「入る」ように見えますが、RMI サーバー自体には到達しません。
私の最初の推測では、「Java コントロール パネル」のようなものを使用して、おそらく RMI トラフィックを制限している可能性のあるセキュリティ設定を調整することでしたが、そのようなスイッチを認識できません。
誰でもこれに関する手がかりを提供できますか?
- 接続がJavaに到達することを確認する方法はありますか?
- RMI サーバーに渡される前にこれをブロックしている Java セキュリティでしょうか?
提案やガイダンスをいただければ幸いです。
(編集、詳細を追加...)
もう少し情報は次のとおりです...
- LAN内では、サーバーPCは192.168.0.110として知られています
- 遠隔地から (WAN 経由で) サーバー PC は 110.142.83.167 として知られています。
- リモート クライアントは RMI サーバー オブジェクトを取得しているようです
- スタック トレース (詳細は後述) には、「接続がホストへの接続を拒否しました: 192.168.0.110;」があります。
- そのため、どの IP アドレスであるかについて混乱があるようです。クライアントは 110.142.83.167 を要求しましたが、サーバーはそれが 192.168.0.110 であると認識しています
スタックトレースは以下の通りです...
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)
コードのスーパーカットダウンバージョン(ボイラープレートなどなし)に続いて...
RMI サーバーで ...
// 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);
}
}
サーバーRMIオブジェクト ...
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);
}
}
}
各 RMI クライアントで ...
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);
}
}