"ClassCastException: $Proxy0 cannot be cast" error while creating simple RMI application

Booyaches picture Booyaches · Mar 8, 2012 · Viewed 34.1k times · Source

I am creating my first, very simple RMI client-server application.

Here is the code:

Interface "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; 

}

Interface implementation "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";
    }

}

Here is my main class of the server "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'.");

    }

}

And this is my client "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);


    }

}

Now when I try to run it:

  1. I navigate to bin directory of my project using Terminal
  2. I run rmiregistry from there
  3. I run my CommunicationServer from new Terminal window (and it prints out the messages so it seems to work)
  4. I open third terminal window and when i try to run my CommunicationClient it throws an exception.

java itu.exercies.RMI.client.CommunicationClientException in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to itu.exercies.RMI.server.CommunicationImpl at itu.exercies.RMI.client.CommunicationClient.main(CommunicationClient.java:14)

So far I have tried to fix it by creating a stub of 'CommunicationImpl' object using rmic but now instead of '$Proxy0' the error refers to 'CommunicationImpl_Stub':

Exception in thread "main" java.lang.ClassCastException: itu.exercies.RMI.server.CommunicationImpl_Stub cannot be cast to itu.exercies.RMI.server.CommunicationImpl at itu.exercies.RMI.client.CommunicationClient.main(CommunicationClient.java:14)

At this point I have no idea were to look for errors. Can anybody give me any suggestions?

Answer

skaffman picture skaffman · Mar 8, 2012

Replace

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

with

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

CommunicationImpl is the server implementation of the ICommunication. The client neither knows nor cares about the implementation, only the interface.