2015-01-11 1 views
0

im работает над дифференциатором, который работает. Теперь я хочу, чтобы он был удаленным. Итак, у меня есть «Function» -Interface, класс «Funktion», реализующий интерфейс Function. Затем у меня есть Сервер, клиент и общий интерфейс службы. Часть кода:

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; 

} 

} 

Класс "Funktion":

public class Funktion extends UnicastRemoteObject implements Function, Serializable { 

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

Интерфейс "Функция":

public interface Function extends java.rmi.Remote { 

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

Сервер:

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); 
} 

} 

И последнее , служебный интерфейс:

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; 
} 

Извините за эту стену кода, я просто думаю, что может потребоваться найти ошибку. Прежде всего, если я использую услугу как:

Service<String, Double, Double> service; , а затем разобрать строку на «стороне сервера» и возвращает результат его прекрасно работает. Листинг: service = (Service<String, Double, Double>) Naming.lookup(url); не создает никаких проблем.

Однако я пытаюсь заставить его работать с объектами Funktion. Я всегда получаю исключение из названия. Я googled alot и люди, которые говорят, что важно бросить на интерфейс, а не на конкретный класс. Я думаю, что я кастинг на интерфейс с

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

Я также попытался:

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

но получить такое же исключение.

Я надеюсь, что кто-то может мне помочь. С наилучшими пожеланиями

Edit: Работа с интерфейсом «Function» в результатах клиента и сервера в этом исключения:

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 
+1

Ваш код говорит, что 'class DifferentiatorService' ...' реализует службу '. Вы пробовали кастинг с этим конкретным типом интерфейса, или это Funktion ** en ** опечатка? – halfbit

+0

Ах, извините, я переименовал класс Funktionen в Funktion, так как имя было нехорошим. Его все тот же класс. Просто отредактировал его. Спасибо за подсказку. – FelRPI

+1

Жаль вас беспокоить, но вы уверены, что исключение происходит на 'Naming.lookup'? Я спрашиваю, потому что во время «службы».execute' RMI может потребоваться передать удаленный прокси (на сервере для «f» клиента) в качестве первого аргумента 'DifferentiatorService.execute (Funktion ...)', который снова является классом, а не интерфейсом ('Function' ?). – halfbit

ответ

1

Вы не можете отлитые заглушку для класса реализации Funktion. Это не экземпляр этого класса. Это экземпляр удаленного интерфейса. Итак, отбросьте его на удаленный интерфейс: Function. И измените подписи во всем классе Service соответственно.

NB Вы просите, чтобы эти имена были одинаковыми. Измените первый на FunctionImpl, FunctionServer, FunctionRemoteObject или что угодно.