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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:06:01