【问题标题】:Java RMI Proxy issueJava RMI 代理问题
【发布时间】:2010-05-12 18:41:33
【问题描述】:

我收到此错误:

 java.lang.ClassCastException: $Proxy0 cannot be cast to rmi.engine.Call
        at Main.main(Main.java:39)

我的 AbstractCall 类都扩展了 Remote

呼叫:

public class Call extends UnicastRemoteObject implements rmi.engine.Abstract {

    public Call() throws Exception {
        super(Store.PORT, new RClient(), new RServer());
    }

    public String getHello() {
        System.out.println("CONN");
        return "HEY";
    }
} 

摘要:

public interface Abstract extends Remote {

    String getHello() throws RemoteException;

}

这是我的主要内容:

public static void main(String[] args) {
    if (args.length == 0) {
        try {
            System.out.println("We are slave ");
            InetAddress ip = InetAddress.getLocalHost();
            Registry rr = LocateRegistry.
                getRegistry(ip.getHostAddress(), Store.PORT, new RClient());

            Object ss = rr.lookup("FILLER");

            System.out.println(ss.getClass().getCanonicalName());
            System.out.println(((Call)ss).getHello());

        } catch (Exception e) {
            e.printStackTrace();
        }
    } else {
        if (args[0].equals("master")) {
            // Start Master
            try {
                RMIServer.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

Netbeans 说问题出在第 39 行,即

    System.out.println(((Call)ss).getHello());

输出如下所示:

运行:

We are slave 
Connecting 10.0.0.212:5225
$Proxy0
java.lang.ClassCastException: $Proxy0 cannot be cast to rmi.engine.Call
        at Main.main(Main.java:39)

BUILD SUCCESSFUL (total time: 1 second)

我在 cmd 中运行一个 master 监听端口 5225。

【问题讨论】:

  • 对我真的很有帮助。因为我也在创建服务器实现的对象而不是接口。您应该记住,无论何时调用服务器程序,即远程方法,您都应该通过定义的接口调用它们。

标签: java proxy rmi


【解决方案1】:

$Proxy0类是dynamic proxy,即java在运行时生成一个类。

这个类应该实现接口Abstract,但不扩展Call。所以你不能将它向下转换为Call(这会产生一个类转换),但将它向下转换为Abstract 应该没问题。

如果你使用 RMI,你应该只通过接口与远程对象通信。

PS:Abstract 是一个令人困惑的名字。我真的以为你首先说的是abstract class。如果可能的话,我会重命名它。 rmi.engine 也一样,更喜欢 org.myproject 之类的东西,以避免与 JDK 的内部类混淆。

【讨论】:

  • 非常感谢您指出明显的错误!救命稻草!