RMI连接报错:com.sun.proxy.$Proxy0无法转换为Client.AdditionInterface
解决RMI代理类强转失败:
com.sun.proxy.$Proxy0 cannot be cast to Client.AdditionInterface 这个错误的核心原因很明确:你在Client和Serveur两个不同包下分别定义了同名的AdditionInterface,导致JVM认为这是两个完全不同的类。
Java中判断两个类是否为同一类型,依赖的是「全限定类名(包名+类名)+ 类加载器」的组合。你的Server端实现的是Serveur.AdditionInterface,而客户端试图把RMI返回的代理对象强转为Client.AdditionInterface——这两个接口在JVM眼里毫无关系,自然会抛出类型转换异常。
正确的解决方案:统一接口到公共模块
你需要把AdditionInterface抽离到一个独立的公共包(比如common),让Client和Server都依赖这个公共接口,保证两边使用的是同一个全限定名的接口。
1. 定义公共远程接口
创建一个独立的common包,编写你的远程接口:
package common; import java.rmi.Remote; import java.rmi.RemoteException; // 远程接口必须继承Remote public interface AdditionInterface extends Remote { // 所有远程方法必须声明抛出RemoteException int add(int num1, int num2) throws RemoteException; }
2. 改造Server端代码
Server端的实现类和主类都要引用这个公共接口:
package Serveur; import common.AdditionInterface; import java.rmi.server.UnicastRemoteObject; import java.rmi.RemoteException; // 实现公共接口,同时继承UnicastRemoteObject(用于导出远程对象) public class Addition extends UnicastRemoteObject implements AdditionInterface { public Addition() throws RemoteException { super(); } @Override public int add(int num1, int num2) throws RemoteException { return num1 + num2; } }
Server启动类:
package Serveur; import common.AdditionInterface; import java.rmi.Naming; import java.rmi.registry.LocateRegistry; public class AdditionServer { public static void main(String[] argv) { try { // 注册RMI注册表端口 LocateRegistry.createRegistry(1099); AdditionInterface hello = new Addition(); // 绑定远程对象到注册表 Naming.rebind("rmi://localhost/AdditionService", hello); System.out.println("Addition Server is ready!"); } catch (Exception e) { System.err.println("Server Error: " + e.getMessage()); e.printStackTrace(); } } }
3. 改造Client端代码
客户端同样引用公共接口进行远程调用:
package Client; import common.AdditionInterface; import java.rmi.Naming; public class AdditionClient { public static void main(String[] args) { try { // 查找远程对象 AdditionInterface service = (AdditionInterface) Naming.lookup("rmi://localhost/AdditionService"); int result = service.add(10, 20); System.out.println("10 + 20 = " + result); } catch (Exception e) { System.err.println("Client Error: " + e.getMessage()); e.printStackTrace(); } } }
额外注意事项
- 确保公共接口的class文件(或者打包成jar)被添加到Client和Server的类路径中,两边的类加载器能加载到同一个
common.AdditionInterface类。 - 远程接口必须严格遵循RMI规范:继承
Remote,所有远程方法抛出RemoteException。 - 如果你的实现类不想继承
UnicastRemoteObject,可以在构造方法中手动调用UnicastRemoteObject.exportObject(this, 0)来导出远程对象。
内容的提问来源于stack exchange,提问作者user8143344
相关产品推荐
相关产品推荐

