Java RMI - 访问不同机器上的 RMI 注册表对象 - AccessControlException?

Posted

技术标签:

【中文标题】Java RMI - 访问不同机器上的 RMI 注册表对象 - AccessControlException?【英文标题】:Java RMI - Accessing RMI Registry Objects on a Different Machine - AccessControlException? 【发布时间】:2011-11-08 15:12:04 【问题描述】:

我试图让一台机器上的客户端通过 Java RMI 与另一台机器上的服务器通信。我将服务器部署在端口 Y 上的主机 IP X 上。然后我尝试让客户端在服务器上查找远程对象,但出现以下异常:

Exception in thread "main" java.security.AccessControlException: access denied (java.net.SocketPermission <IP address>:<port> connect,resolve)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
    at java.security.AccessController.checkPermission(AccessController.java:546)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
    at java.lang.SecurityManager.checkConnect(SecurityManager.java:1034)
    at java.net.Socket.connect(Socket.java:524)
    at java.net.Socket.connect(Socket.java:478)
    at java.net.Socket.<init>(Socket.java:375)
    at java.net.Socket.<init>(Socket.java:189)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
    at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at nursestation.NurseStation.subscribeToPatients(NurseStation.java:65)
    at nursestation.NurseStation.<init>(NurseStation.java:42)
    at nursestation.perf.SimplePerfTest.main(SimplePerfTest.java:28)

请注意,客户端和服务器都使用允许所有权限的策略文件运行。 RMI 注册表也在服务器上运行。关于我为什么会收到此异常的任何想法?我该怎么做才能让客户端与运行在不同服务器上的服务器通信?

更新:

政策文件

grant 
  permission java.security.AllPermission;
;

客户端启动 - 为 Eclipse 使用 RMI 插件

    启动 RMI 注册表 使用上面显示的 java.security.policy 的指定策略文件和指向我的项目工作区代码的 java.rmi.server.codebase 执行“java BedsideMonitorMain patient1 vital1 vital2” patient1 对象已绑定到 RMI 注册表

服务器启动

    使用上面显示的 java.security.policy 的指定策略文件和指向我的项目工作区代码的 java.rmi.server.codebase 执行“java NurseStationMain patient1”

【问题讨论】:

您确定您正确使用了策略文件吗?这篇文章***.com/questions/2427473/… 暗示您可以在没有正确设置策略文件时获取此堆栈跟踪。可能值得编辑问题以显示策略文件以及您如何调用客户端和服务器。 还要确保您的身份验证设置正确。尝试添加-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false 看看是否有效。 使用 -Djava.security.debug=access,failure 运行您的客户端,您将确切看到哪些保护域授予/拒绝了哪些权限,因此您还将看到您的 .policy 文件是否实际上,显然不是。 我会尽快运行它。目前,我们注意到远程处理在我团队成员的一台机器上工作,但不是我的。我觉得这可能与防火墙有关? 【参考方案1】:

所以我发现了根本问题。显然,两台机器都有不同的 Eclipse RMI 插件许可证密钥,这不允许两台机器相互通信。当我使两台机器上的许可证密钥相同时,我就能够让客户端和服务器相互通信。就我的目的而言,这就足够了,因为我没有在生产环境中使用这个系统(它是用于课堂项目)。我很好奇这个问题的“最佳”解决方案是什么。

【讨论】:

就我个人而言,我看不出 Eclipse 许可证密钥与基本的 RMI Java 连接有什么关系。你能解释一下吗?

以上是关于Java RMI - 访问不同机器上的 RMI 注册表对象 - AccessControlException?的主要内容,如果未能解决你的问题,请参考以下文章

4_分布式通信框架RMI

远程方法调用(RMI)原理与示例

远程方法调用(RMI)原理与示例 (转)

Java网络编程基础— RMI分布式网络编程

RMI 客户端无法查找服务器 - java.rmi.UnmarshalException

java基础十一[远程部署的RMI](阅读Head First Java记录)