Ошибка «ClassCastException: $ Proxy0 не может быть приведена» при создании простого приложения RMI - PullRequest
12 голосов
/ 08 марта 2012

Я создаю свое первое, очень простое клиент-серверное приложение RMI.

Вот код:

Интерфейс "ICommunication"

package itu.exercies.RMI.server;

    import java.rmi.Remote;
    import java.rmi.RemoteException;

public interface ICommunication extends Remote  
{
    public String doCommunicate(String name) throws RemoteException; 

}

Реализация интерфейса "CommunicationImpl":

package itu.exercies.RMI.server;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class CommunicationImpl extends UnicastRemoteObject implements ICommunication {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public CommunicationImpl() throws RemoteException {
        super();

    }

    @Override
    public String doCommunicate(String name) throws RemoteException {

        return "Hello this is server , whats up " +name+ " ?!\n";
    }

}

Вот мой основной класссервера "CommunicationServer":

package itu.exercies.RMI.server;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;


public class CommunicationServer {
    /**
     * @param args
     * @throws RemoteException 
     * @throws MalformedURLException 
     */
    public static void main(String[] args) throws RemoteException, MalformedURLException {
        CommunicationImpl imp = new CommunicationImpl();
        Naming.rebind("CommunicationImpl", imp);
        System.out.println("Server started...");
        System.out.println("Object successfully registered. It is bound to the name 'CommunicationImpl'.");

    }

}

А это мой клиент "CommunicationClient":

package itu.exercies.RMI.client;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import itu.exercies.RMI.server.CommunicationImpl;

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

        String url = new String("rmi://localhost/CommunicationImpl");
        CommunicationImpl comm = (CommunicationImpl)Naming.lookup(url);
        String reply = comm.doCommunicate("Wiktor");
        System.out.println(reply);


    }

}

Теперь, когда я пытаюсь запустить его:

  1. Я перехожу в каталог bin моего проекта, используя Terminal
  2. Я запускаю оттуда rmiregistry
  3. Я запускаю CommunicationServer из нового окна Terminal (и он распечатывает сообщения, чтобы он работал)
  4. Я открываю третье окно терминала и при попытке запустить CommunicationClient выдает исключение.

java itu.exercies.RMI.client.CommunicationClientException в потоке "main"java.lang.ClassCastException: $ Proxy0 не может быть приведен к itu.exercies.RMI.server.CommunicationImpl в itu.exercies.RMI.client.CommunicationClient.main (CommunicationClient.java:14)

Итакпока я пытался это исправитьсоздание заглушки объекта CommunicationImpl с использованием rmic, но теперь вместо $ Proxy0 ошибка относится к CommunicationImpl_Stub:

Исключение в потоке "main" java.lang.ClassCastException: itu.exercies.RMI.server.CommunicationImpl_Stub нельзя преобразовать в itu.exercies.RMI.server.CommunicationImpl в itu.exercies.RMI.client.CommunicationClient.main (CommunicationClient.java:14)

На данный момент я понятия не имею, нужно было искать ошибки.Кто-нибудь может дать мне какие-либо предложения?

1 Ответ

23 голосов
/ 08 марта 2012

Заменить

CommunicationImpl comm = (CommunicationImpl) Naming.lookup(url);

на

ICommunication comm = (ICommunication) Naming.lookup(url);

CommunicationImpl - серверная реализация ICommunication.Клиент не знает и не заботится о реализации, только интерфейс.

...