Java RMI 使用或不使用 SecurityManager

标签 java rmi securitymanager connectexception

经过大量搜索和反复试验,我仍然无法确定是否需要安全管理器,如果需要,如何让它发挥作用。

启动服务器的代码:

    Registry registry;
    try {
        System.setProperty("java.security.policyfile", "\\\\...\\security.policy");
        if (System.getSecurityManager() == null) {
            RMISecurityManager securityManager = new RMISecurityManager();
            System.setSecurityManager(securityManager);
        }
        registry = LocateRegistry.createRegistry(port);
        registry.bind(serviceName, remote);
        System.out.println("RMI registry created.");
    } catch (RemoteException e) {
        //error means registry already exists
        System.out.println("RMI registry already exists.");
    }
    System.setProperty("java.rmi.server.hostname", hostURL);
    Naming.rebind(hostURL, remote);

服务器上的错误信息:

D:\>java -jar Server.jar
RMI server starting up
RMI registry created.
Exception in thread "main" ...Exception: Unable to start the Remote Server Server[UnicastServerRef [liveRef: [...]]
        at ServiceProvider.start(ServiceProvider.java:64)
        at Server.main(Server.java:76)
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.rmi.server.hostname" "write")
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPermission(Unknown Source)
        at java.lang.System.setProperty(Unknown Source)
        at ServiceProvider.start(ServiceProvider.java:61)
        ... 1 more

策略文件:

grant {
   permission java.security.AllPermission;
 }; 

感谢任何能提供帮助的人。

我承认我什至不确定我是否需要安全管理器,但当我没有使用它时,我得到了以下信息。至少在这里服务器启动了,我能够从客户端连接到它(提供的 IP 地址未用于获取连接,这是内部计算出来的)。但是,当我尝试使用服务器中的一种方法时,我收到以下错误消息,即使只是“printTime”,它应该只在服务器端显示时间。

Exception in thread "main" java.rmi.ConnectException: Connection refused to host: ...IP...; nested exception is: 
java.net.ConnectException: Connection timed out: connect

再次感谢。

编辑:

好的,我已经删除了安全管理器,因为所有需要的类都在我的接口(interface)中,它包含在我的客户端和服务器项目中。 @EJP,当涉及到 Java 和 RMI 时,您显然非常了解。我很重视您的意见。

我继续收到连接超时错误。我知道这很常见,但我已经尝试了所有我能想到的方法。
我添加了属性:java.rmi.server.codebase 以及我的 lib 文件夹中的所有 jar 文件。

一位 friend 向我指出,我的问题是我包含了 POJO(普通旧 Java 对象),它们对于 RMI 来说太复杂而无法传输。但是我所有的 POJO 都是可序列化的。此外,我能够在我的本地主机上运行服务器并使用客户端应用程序毫无问题地访问它。这告诉我 RMI 可以完成我要求的工作。

直到我在远程机器上运行服务器然后启动我的客户端,我才收到此连接错误。我的客户端能够连接,但随后在 printTime 方法处挂断。

运行客户端的代码:

  final Registry registry = LocateRegistry.getRegistry(hostURL, port);
  final HXTTDBFInterface serverIX = (HXTTDBFInterface) registry.lookup(serviceName);

  //Start with simple Server Connection Test
  serverIX.printTime();  //CONNECTION TIMED OUT ERROR HERE
  String time = serverIX.getTime();
  System.out.println("Time From Server: " + time);

如果有人对尝试的事情有任何建议,我会洗耳恭听。 提前致谢。

进一步说明: 我使用命令 netstat -a 并显示:

LocalAddress       ForeignAddress    State
0.0.0.0:1099       SERVERNAME:0      LISTENING
[::]:1099          SERVERNAME:0      LISTENING
XX.XX.XX.XX:53373  SERVERNAME:1099   ESTABLISHED

(在许多其他行中)

这是否意味着它真的在听?

最佳答案

如果对等方使用代码库工具动态地为您提供类,您只需要为 RMI 安装安全管理器。否则,是否使用一个完全取决于您。除非您知道它是必需的,否则我会避免使用它。

关于Java RMI 使用或不使用 SecurityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22155865/

相关文章:

java - 如何使用jsoup编辑html标签中的所有文本值

java - RMI - 引用并使用远程对象作为 HashMap 中的 "key"

RMI 中的 java.lang.ClassNotFoundException,没有禁用安全管理器 RMI 类加载器

java - 在安全管理器下解析许多域后程序内存不足?

java - SQL 性能 : Multiple Binds or Bind to One SQL Variable for Re-use?

java - 如何在java中使用derby在想要的位置设置想要的数据库

java - 创建字典并将其作为映射传递给 Robot Framework 中的 Java 方法

Java Rmi 未知主机异常

java - 为当前线程禁用 Java 反射

java - 使用Java SecurityManager阻止我读取文件