FelRPI
FelRPI

Reputation: 429

RMI: java.lang.ClassCastException: com.sun.proxy.$Proxy1 cannot be cast to Funktion

im working on a differentiator which is working. Now i want it to be remote aswell. So i have a "Function"-Interface, a "Funktion"-class implementing the Function interface. Then i have a Server, a client and a generic service interface. Part of the code:

public class DifferentiatorClient {

public static void main(String[] args) throws RemoteException, MalformedURLException, IllegalArgumentException, NotBoundException, RecognitionException {
    execute();
}

public static Double execute() throws RemoteException, MalformedURLException, NotBoundException, IllegalArgumentException, RecognitionException {
    Service<Funktion, Double, Double> service;
    String url = "//localhost/DifferentiatorService";
    Double r;
    Script script = new Script();
    Funktion f = script.getFunction("f");
    service = (Service<Funktion, Double, Double>) Naming.lookup(url);
    r = service.execute(f, 2.0);
    return r;

}

}

The class "Funktion":

public class Funktion extends UnicastRemoteObject implements Function, Serializable {

/**
 * 
 */
private static final long serialVersionUID = -1234132759512350836L;
//some methods
}

The interface "Function":

public interface Function  extends java.rmi.Remote {

double eval(final double ... args) throws IllegalArgumentException, RecognitionException, RemoteException;
}

The server:

public class DifferentiatorService extends java.rmi.server.UnicastRemoteObject
    implements Service<Funktion, Double, Double> {

private static final long serialVersionUID = -3236697150408344006L;

protected DifferentiatorService() throws RemoteException {

}

@Override
public String getName() throws RemoteException {
    return "DifferentiatorService";

}

public Double execute(Funktion f, Double... args) throws RemoteException {
    Differentiator diff = new Differentiator();
    double result = diff.differentiate(f, args[0]);
    return result;
}

public static void main(String[] args) throws Exception {
    String url = "//localhost/DifferentiatorService";
    Registry registry = LocateRegistry.createRegistry(1099);
    DifferentiatorService service = new DifferentiatorService();
    Naming.rebind(url, service);
}

}

And last, the service interface:

public interface Service<T,A,R> extends java.rmi.Remote {

String getName() throws java.rmi.RemoteException;

R execute(T task,A ... args) throws java.rmi.RemoteException;
}

Sorry for this wall of code, i just think it might be necessary to find the error. First of all, if i use a service like:

Service<String, Double, Double> service; and then parse the String on the "server-side" and returning the result its working perfectly. The cast: service = (Service<String, Double, Double>) Naming.lookup(url); doesnt make any problems then.

However im trying to make it work with Funktion objects. I always get the exception from the title. I googled alot and people where saying its important to cast to an interface and not to an concrete class. I think i am casting to an interface with

service = (Service<Funktion, Double, Double>) Naming.lookup(url);

I also tried:

service = (Service<Function, Double, Double>) Naming.lookup(url);

but getting the same exception.

I hope someone can help me. Best regards

Edit: Working with the interface "Function" in client and server results in this exception:

Exception in thread "main" java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: 
    java.io.EOFException
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:229)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
    at com.sun.proxy.$Proxy1.execute(Unknown Source)
    at de.lab4inf.wrb.DifferentiatorClient.execute(DifferentiatorClient.java:25)
    at de.lab4inf.wrb.DifferentiatorClient.main(DifferentiatorClient.java:13)
Caused by: java.io.EOFException
    at java.io.DataInputStream.readByte(DataInputStream.java:267)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:215)
    ... 6 more
 

Upvotes: 0

Views: 7606

Answers (1)

user207421
user207421

Reputation: 311023

You can't cast the stub to the implementation class Funktion. It isn't an instance of that class. It's an instance of the remote interface. So, cast it to the remote interface: Function. And change the signatures throughout the Service class accordingly.

NB You're asking for trouble keeping these names so similar. Change the first to FunctionImpl, FunctionServer, FunctionRemoteObject, or whatever.

Upvotes: 1

Related Questions