RMI [java.rmi.UnmarshalException] 问题解决

本文针对Java RMI出现的UnmarshalException及ClassNotFoundException问题提供了解决方案。通过设置安全管理和连接policy文件,有效避免了远程调用时的安全限制导致的异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

未经本人许可,不得转载该文!


错误描述:

java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
    java.lang.ClassNotFoundException: compute.ComputeEngine (no security manager: RMI class loader disabled)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at java.rmi.Naming.lookup(Naming.java:101)
    at connection.RMIConnect.run(RMIConnect.java:128)
    at java.lang.Thread.run(Thread.java:722)


解决方法:

按步骤执行以下方法:

1. 在你的客户端绑定端口时,添加以下代码。

try {
                System.setSecurityManager(new java.rmi.RMISecurityManager());
                remote = (Compute) Naming.lookup("rmi://localhost:1099/zhaopeng");
            } catch (RemoteException ex) {
                Logger.getLogger(RMIConnect.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NotBoundException ex) {
                System.out.println("waiting bound....");
            } catch (MalformedURLException ex) {
                System.out.println(ex.getMessage());
            }
2.编译时,连接policy文件

java -Djava.security.policy=client_policy.txt <你的客户端,例如europeanproject.GUIFrame>


注意: client_policy.txt

grant{
    permission   java.security.AllPermission;
}; 

3. 解决问题了!


不要听信网上乱七八糟的解决方法,这个80%都行!

<think>我们正在讨论Java RMI中的`java.rmi.server.hostname`系统属性。根据引用,这个属性用于指定RMI服务器在注册RMI注册表时使用的主机名或IP地址。当RMI服务器在具有多个网络接口(例如,多个IP地址)的机器上运行时,或者当服务器位于NAT或防火墙后面时,这个属性尤为重要。如果不设置,RMI可能会选择一个不正确的网络接口(如127.0.0.1或私有IP),导致远程客户端无法连接。 配置方法有两种: 1. 在启动JVM时通过命令行参数设置:`-Djava.rmi.server.hostname=你的公网IP或域名` 2. 在代码中设置系统属性:`System.setProperty("java.rmi.server.hostname", "你的公网IP或域名");` 注意:这个属性必须在创建RMI注册表或绑定远程对象之前设置,因为RMI在导出远程对象时会使用这个主机名。 例如,在代码中设置: ```java public void start() throws Exception { System.setProperty("java.rmi.server.hostname", "118.31.168.198"); LocateRegistry.createRegistry(30101); RMIServer h = new RMIServer(); Naming.rebind("rmi://127.0.0.1:30101/Feng", h); System.out.println("RMI服务在30101端口启动"); } ``` 或者,在启动命令中设置: ``` java -Djava.rmi.server.hostname=118.31.168.198 -jar your_application.jar ``` 在分布式测试工具如JMeter中,这个设置同样重要,因为它确保从机(slave)能够正确地连接到主机(master)的RMI服务。 相关问题: 1. 为什么在分布式JMeter测试中必须设置`java.rmi.server.hostname`? 2. 如何诊断和解决Java RMI连接被拒绝的问题? 3. 除了设置`java.rmi.server.hostname`,还有哪些配置可以确保RMI服务在复杂网络环境中正常工作? 4. RMI注册表(Registry)和远程对象绑定(bind/rebind)之间有什么关联? 5. 在Docker容器中运行RMI服务时,如何配置`java.rmi.server.hostname`?</think>### Java RMI 服务器主机名参数详解 `java.rmi.server.hostname` 是 Java RMI(远程方法调用)框架中的关键系统属性,用于指定 RMI 服务器对外暴露的主机名或 IP 地址。当服务器有多个网络接口或位于 NAT/防火墙后时,必须正确配置该参数才能确保客户端正常连接。 #### 核心作用 1. **地址绑定控制** 指定 RMI 服务器在注册表中发布的网络地址(而非默认的本地地址) ```java // 示例:设置服务器公网IP System.setProperty("java.rmi.server.hostname", "118.31.168.198"); ``` 2. **解决连接问题** 当客户端收到 "Connection refused" 错误时(如引用[2]所述),通常是因为服务器注册了不可达的地址(如 127.0.0.1) 3. **分布式系统支持** 在 JMeter 分布式测试等场景中(引用[3][5]),确保从机能解析到主机的正确地址 #### 配置方法 **方式1:代码中动态设置(推荐)** 在创建 RMI 注册表前设置系统属性: ```java public void startRMIServer() throws Exception { // 关键配置:设置主机名/IP System.setProperty("java.rmi.server.hostname", "118.31.168.198"); // 创建注册表并绑定服务 LocateRegistry.createRegistry(30101); Naming.rebind("rmi://118.31.168.198:30101/ServiceName", new ServiceImpl()); System.out.println("RMI服务在30101端口启动"); } ``` **方式2:JVM 启动参数** 通过 `-D` 参数指定: ```bash java -Djava.rmi.server.hostname=118.31.168.198 -jar your_app.jar ``` **方式3:环境变量配置** 适用于容器化部署(引用[4]): ```bash # Tomcat示例 export CATALINA_OPTS="$CATALINA_OPTS -Djava.rmi.server.hostname=192.168.40.103" ``` #### 注意事项 1. **时机要求** 必须在 `LocateRegistry.createRegistry()` 或 `Naming.rebind()` 前设置,否则无效[^1] 2. **网络环境** - 公网部署需使用公网 IP 或域名 - 云环境需配合安全组开放端口 3. **客户端匹配** 客户端连接地址需与服务器配置一致: ```java // 客户端连接示例 String rmiUrl = "rmi://118.31.168.198:30101/ServiceName"; Service service = (Service) Naming.lookup(rmiUrl); ``` #### 常见问题解决 - **错误:ObjID already in use** 检查端口冲突(引用[4]),确保每次重启前注销服务 - **分布式测试失败** JMeter 需在所有节点设置一致的主机名(引用[3][5]) - **NAT 穿透问题** 在防火墙后部署时,需同时配置端口转发规则 ### 相关问题 1. 如何诊断 Java RMI 的 "Connection refused" 错误? 2. 在 Docker 容器中部署 RMI 服务需要哪些特殊配置? 3. RMI 与 Web Service 在分布式通信中的优劣比较? 4. 如何实现 RMI 服务的动态负载均衡? 5. JMeter 分布式测试中除了主机名还需要哪些关键配置?[^3][^5] [^1]: 引用自代码示例,说明配置时机的重要性 [^2]: 引用关于 RMI 连接问题的通用解决方案 [^3]: 引用 JMeter 分布式测试中的实际应用场景 [^4]: 引用容器环境配置示例 [^5]: 引用分布式测试的端口配置注意事项
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值