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

RMI跨机器调用报java.rmi.AccessException,远程绑定请求被拒绝

解决RMI Registry.rebind的AccessException问题

这个错误我之前在跨机器部署RMI应用时也碰到过,核心原因是RMI注册表默认只允许本地主机执行rebind/unbind这类修改注册表的操作,你的客户端IP(10.0.0.71)是远程主机,所以直接被拦截了。下面分两种场景给你解决方案:

场景1:客户端错误地执行了rebind操作(最常见情况)

正常的RMI流程里,rebind是服务器端的职责——服务器把实现类绑定到本地注册表,客户端只需要通过lookup获取远程对象即可。

检查并修正代码:

  • 先排查你的客户端代码,是不是不小心写了类似这样的错误逻辑:
// 客户端错误代码示例
Registry registry = LocateRegistry.getRegistry("10.0.1.100");
registry.rebind("Calculator", someObject); // 客户端不该执行这个操作!
  • 把rebind逻辑完全移到服务器端,服务器端的正确绑定代码示例:
// 服务器端代码
package com.simplecalc.server;

import com.simplecalc.commons.Calculator;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class CalculatorImpl implements Calculator {
    @Override
    public float add(float a, float b) {
        return a + b;
    }

    public static void main(String[] args) {
        try {
            Calculator calc = new CalculatorImpl();
            // 导出远程对象
            Calculator stub = (Calculator) UnicastRemoteObject.exportObject(calc, 0);
            // 创建或获取本地注册表(默认端口1099)
            Registry registry = LocateRegistry.createRegistry(1099);
            // 将对象绑定到注册表
            registry.rebind("Calculator", stub);
            System.out.println("Calculator server is ready");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 客户端只需要通过lookup获取远程对象并调用方法:
// 客户端正确代码示例
package com.simplecalc.client;

import com.simplecalc.commons.Calculator;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class CalculatorClient {
    public static void main(String[] args) {
        try {
            // 连接服务器的RMI注册表
            Registry registry = LocateRegistry.getRegistry("10.0.1.100", 1099);
            // 获取远程计算器对象
            Calculator calc = (Calculator) registry.lookup("Calculator");
            // 调用远程加法方法
            float result = calc.add(3.2f, 5.8f);
            System.out.println("Addition result: " + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

场景2:确实需要远程操作注册表(不推荐,存在安全风险)

如果你的业务场景必须让远程客户端修改注册表,那需要通过安全策略文件开放权限:

  1. 在服务器端创建一个权限策略文件,比如命名为rmi.policy,内容如下:
grant {
    permission java.security.AllPermission;
};
  1. 启动RMI注册表时指定这个策略文件:
rmiregistry -J-Djava.security.policy=rmi.policy &
  1. 启动服务器JVM时也要指定策略和服务器的可访问IP(避免客户端拿到本地回环IP导致连接失败):
java -Djava.security.policy=rmi.policy -Djava.rmi.server.hostname=10.0.1.100 com.simplecalc.server.CalculatorImpl

额外注意事项

  • 确保服务器的防火墙开放了RMI默认端口1099,以及RMI对象的通信端口;如果不想用随机端口,也可以通过-Djava.rmi.server.port=xxxx参数固定端口,方便防火墙配置
  • 服务器端必须设置java.rmi.server.hostname为自身的可访问IP(10.0.1.100),否则客户端可能拿到服务器的本地回环IP(比如127.0.0.1),导致无法连接远程对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:49:50