Reputation: 429
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
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
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