You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8升级后RMI Registry连接遇AccessControlPermission权限问题

解决Java 8升级后RMI客户端的AccessControlException权限问题

报错信息:java.security.AccessControlException: access denied ("java.net.SocketPermission" "localhost:1099" "listen,resolve")

问题背景

代码最初基于Java 6及更低版本开发,升级到Java 8后,因Java 8安全策略更严格,建立RMI Registry连接时抛出上述权限错误,已尝试在java.policy文件中为默认RMI端口1099授予权限,但问题未解决。客户端核心代码如下:

package com.aurionpro.reuters;

import com.aurionpro.reuters.service.UpdateCurrencyRates;
import java.io.IOException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Properties;

public final class RMIServiceClient {
   private final String hostname;
   private final int port;
   private final String serviceName;
   private UpdateCurrencyRates currencyRates;
   private Registry registry = null;

   public RMIServiceClient(String appPropFileName, String productName) {
      Properties properties = new Properties();
      ClassLoader loader = Thread.currentThread().getContextClassLoader();

      try {
         properties.load(loader.getResourceAsStream(appPropFileName));
      } catch (IOException var6) {
         var6.printStackTrace();
      }

      this.hostname = properties.getProperty("rmiclient." + productName + ".registry.host");
      this.port = Integer.parseInt(properties.getProperty("rmiclient." + productName + ".registry.port"));
      this.serviceName = properties.getProperty("rmiclient." + productName + ".registry.serviceName");
   }

   public UpdateCurrencyRates getCurrencyRatesService() throws RemoteException, NotBoundException {
      SecurityManager securityManager = new SecurityManager();
      System.setSecurityManager(securityManager);
      this.registry = LocateRegistry.getRegistry(this.hostname, this.port);
      this.currencyRates = (UpdateCurrencyRates)this.registry.lookup(this.serviceName);
      return this.currencyRates;
   }
}

问题分析

  1. 权限配置误区:之前给java.policy配置的是listen,resolve权限,但RMI客户端是主动连接Registry,需要的是connect,resolve权限,listen是服务端绑定端口时才需要的权限,客户端不需要。
  2. 手动设置SecurityManager:Java 8中,客户端场景下默认不需要手动设置SecurityManager,手动设置后会强制启用严格的权限检查,反而会拦截正常的RMI连接操作。

解决方案

方案1:移除手动配置的SecurityManager(推荐)

客户端场景下,Java 8默认的安全策略已经足够支持RMI连接,不需要额外设置SecurityManager。直接注释或删除以下两行代码:

// SecurityManager securityManager = new SecurityManager();
// System.setSecurityManager(securityManager);

修改后重新运行客户端,即可正常连接RMI Registry。

方案2:完善java.policy权限配置(若必须保留SecurityManager)

如果业务场景要求必须启用SecurityManager,需要修正java.policy的权限配置,添加客户端所需的连接权限:

grant {
    // 允许连接本地1099端口的RMI Registry
    permission java.net.SocketPermission "localhost:1099", "connect,resolve";
    // 允许连接本地所有端口(应对RMI动态端口的情况)
    permission java.net.SocketPermission "localhost:*", "connect,resolve";
    // 如果RMI服务在远程主机,添加对应主机的权限
    permission java.net.SocketPermission "your-rmi-server-host:*", "connect,resolve";
};

启动程序时,确保指定了正确的policy文件路径:

java -Djava.security.policy=/path/to/your/custom.policy com.aurionpro.reuters.RMIServiceClient

内容的提问来源于stack exchange,提问作者XERVIS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:23:14