dancing around RMI |
Sep 22 |
How to create a simple client-server application using RMI interface and run it on linux?
- We need to create an interface that extends java.rmi.Remote interface:
public interface IFacade extends Remote { String sayHello() throws RemoteException; // its important exception - its required for object exporting } - Then we are implementing this interface. In
mainmethod we need to get|create a registry object, export our object marked as Remote, and bind it to some name (and actually start the server). Here we can specify the port number for binding.public class Facade implements IFacade { public String sayHello() { return "hello"; } public static void main(String[] args) { int port = 7001; String name = "Facade"; try { IFacade facade = new Facade(); Registry registry = LocateRegistry.createRegistry(port); IFacade stub = (IFacade) UnicastRemoteObject.exportObject(facade, port); registry.bind(name, stub); System.out.println("Server is up and running"); BufferedReader rdr = new BufferedReader( new InputStreamReader(System.in)); while (true) { System.out.println("Type EXIT to shutdown the server."); if ("EXIT".equals(rdr.readLine())) { break; } } registry.unbind(name); UnicastRemoteObject.unexportObject(facade, true); } catch (Exception e) { e.printStackTrace(); } } } - We need to start rmiregistry service:
traut@traut-laptop:~$ rmiregistry Bad port number - using defaultdefault port number is OK
- About client:
public class Client extends Thread { @Override public void run() { super.run(); System.out.println("Client started"); try { Registry registry = LocateRegistry.getRegistry(host, port); IFacade facade = (IFacade) registry.lookup("Facade"); System.out.println(facade.sayHello()); } catch (Exception e) { e.printStackTrace(); return; } } public static void main(String[] args) { int port = 7001; String host = "traut-laptop"; new Client(host, port).start(); new Client(host, port).start(); } } - Fin
A few Interesting things:
This release adds support for the dynamic generation of stub classes at runtime, obviating the need to use the Java(tm) Remote Method Invocation (Java RMI) stub compiler, rmic, to pregenerate stub classes for remote objects. Note that rmic must still be used to pregenerate stub classes for remote objects that need to support clients running on earlier versions.
So, we don’t need to create stub files with rmic program. It must be processed silently undercover from 1.5
I’m not created and used here SecurityManager, policy files, and other boring stuff that documentation advice to use
RMI is still easy-to-understand interface but horrible to implement and to use
ну и как? на практике получилось? :))
ага, после долгих танцев и плясок - завелось.
кстати, я у тебя пару багов нашел - думаю, из-за них не заработало у тебя
а конкретнее - не помнишь?
RMIClient.java:24
и дальше ты делаешь sendFile(fileName);
но у тебя есть переменная static FilesReciever stubFilesReciever;
а в методе sendFile ты делаешь stubFilesReciever.uploadFile(bytes);
т.е. ты вытягиваешь из лукапа один объект, а используешь другой. у тебя shadowing в main методе (локальная переменная перекрывает глобальную [у тебя - статическую])
ты запускал rmiregistry? какую джаву юзал? если < 1.5 то stub файлы нужно было делать самому rmic-ом
вроде бы так
>> но у тебя есть переменная static FilesReciever stubFilesReciever
хм, посомтрел - ага…
это называется “смотрю в книгу и думаю, как сделать лучше”
надо было вначале смотреть, потом делать “лучше” :))
спс за наводку!
хотя и 1.5… но само все не собиралось :///
rmic-ом все собрал… но для этого пришлось линух запускать
блин, надо было тож тогда все промахи залогировать
кстати, главные проблемы были с registry…
при запросе в регистр был глюк “нет объекта”, а при попытке сервера разместить объект - “такой объект уже существует”
strange…
потому я чистить и начал
но у меня такая проблема была когда rmiregistry стартовал с каким-то портом неверным. и тогда, когда я стартовал/стопал/стартовал сервер с запущенным rmiregistry не почистив
чистить? :))))
ага
registry.unbind(name);
UnicastRemoteObject.unexportObject(facade, true);
- в коде
:))))
это, как всегда, было забыто как ненужая формальность )
спс за советы - доберусь до лаб по корке - буду пробовать
Спасибо за статью особенно правильная фраза “RMI is still easy-to-understand interface but horrible to implement and to use”, и отдельно за комменты…..за разбор ошибок
на здоровье