具有客户端异常的简单 RMI 应用程序

Simple RMI application with client-side exception

我使用 Java 8 并创建了一个简单的 RMI 应用程序,但我有一个我不理解的客户端异常。使用 Eclipse 我的应用程序的结构是:

---RMI_project     
-----bin
-------client
----------ImplementazioneMyClassServer_Stub.class
----------InterfacciaMyClassServer.class
----------MainClient.class
-------server
----------ImplementazioneMyClassServer.class
----------InterfacciaMyClassServer.class
----------ImplementazioneMyClassServer_Stub.class
----------ImplementazioneMyClassServer_Skel.class
----------MainServer.class
-----src 
-------client
----------InterfacciaMyClassServer.java
----------MainClient.java
-------server
----------ImplementazioneMyClassServer.java
----------InterfacciaMyClassServer.java
----------MainServer.java

代码如下:

InterfacciaMyClassServer.java

package client;

import java.rmi.*; // necessaria per estendere interfaccia Remote

public interface InterfacciaMyClassServer extends Remote {
 int somma(int a, int b) throws RemoteException;        //unico metodo
}

ImplementazioneMyClassServer.java

package server;

import java.rmi.*;
import java.rmi.server.*;  // per utilizzare UnicastRemoteObject

public class ImplementazioneMyClassServer extends UnicastRemoteObject implements InterfacciaMyClassServer{

    private static final long serialVersionUID = 1L;

    public ImplementazioneMyClassServer() throws RemoteException {      // costruttore
        System.out.println("ok1");
    }

    public int somma(int a, int b) throws RemoteException{      // implementazione metodo somma definito dall'interfaccia
        return a+b;
    }
}

MainServer.java

package server;

import java.rmi.*;

public class MainServer {

    public static void main(String[] args) {

        try{
            ImplementazioneMyClassServer s1 = new   ImplementazioneMyClassServer();

            System.out.println("ok2");

            Naming.rebind("oggetto1", s1);

            System.out.println("ok3");
        }
        catch(Exception e){
            System.out.println(e);
        }
    }

}

MainClient.java

package client;

import java.net.MalformedURLException;
import java.rmi.*;

public class MainClient {

    public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {

        String nomeServer="localhost";        // nome del server o suo    indirizzo IP (per l'esempio localhost=127.0.0.1)
        String nomeOggettoRemoto="oggetto1";   // nome dell'oggetto remoto da richiedere al server 
        String protocollo="rmi";              //protocollo usato, può essere: rmi,ftp,http
        String URLoggettoRemoto=protocollo+"://"+nomeServer+"/"+nomeOggettoRemoto;  // URL completo usato dal client per ottenere riferimento oggetto remoto sul server 

        // cerca all'URL specificato all'interno del registro rmi l'oggetto remoto con nome "oggetto1"
        // e restituisce nella var oggetto il suo riferimento per cui nelle istruzioni successive
        // è possibile riferirsi all'oggetto remoto come se fosse sul client.
        InterfacciaMyClassServer oggetto = (InterfacciaMyClassServer) Naming.lookup(URLoggettoRemoto);

        // uso oggetto remoto
        System.out.println(oggetto.somma(2, 3));
    }

}

我不想下载动态存根class。 这就是为什么我得到 class 存根和 skel,然后我将存根 class 复制到 bin\client 中。 为了获得存根和骨架 classes,我遵循了以下过程:

1) set classpath=C:\JavaWorkspace\RMI_project\src
2) cd C:\JavaWorkspace\RMI_project\src
3) C:\JavaWorkspace\RMI_project\src>javac server/InterfacciaMyClassServer.java
4) C:\JavaWorkspace\RMI_project\src>javac  server/ImplementazioneMyClassServer.java
5) C:\JavaWorkspace\RMI_project\src>rmic -v1.1 server.ImplementazioneMyClassServer

为了 运行 整个应用程序,我遵循了以下过程:

提示 1:

1) set classpath=C:/JavaWorkspace/RMI_project/bin
2) start rmiregistry
3) java server.MainServer

我得到了正确的:

ok1
ok2
ok3

提示2:

1) set classpath=C:/JavaWorkspace/RMI_project/bin
2) java client.MainClient

出现异常的地方:

Exception in thread "main" java.lang.ClassCastException: server.ImplementazioneMyClassServer_Stub cannot be cast to client.InterfacciaMyClassServer 
at client.MainClient.main(MainClient.java:18)

异常是 MainClient 中的第 18 行,但我不明白哪里出了问题。

您在两个包中声明了远程接口。服务器端使用服务器包的远程接口;客户端使用客户端包的远程接口。这两个远程接口是不同的。您不能将一个的实现强制转换为另一个。

你不能这样做。您需要在两端使用同一个包中的同一个远程接口。