Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
laboratoare:laborator04 [2014/11/12 00:18]
Andrei Roșu-Cojocaru removed
laboratoare:laborator04 [2014/11/17 20:54] (current)
Andrei Roșu-Cojocaru [Soluții]
Line 4: Line 4:
 ===== Obiective ==== ===== Obiective ====
  
-  * înțelegerea mecanismului RMI +  * înţelegerea mecanismului RMI pentru dezvoltarea ​unei aplicaţii distribuite,​ prin apelul la distanţă al metodelor unor obiecte rezidente pe server (într-o mașină virtuală Java diferită), ​funcţionalitate de care clientul este informat prin specificaţia în cadrul unei interfeţe care conține semnăturile metodelor ce pot fi invocate; 
-  * distribuirea ​unei aplicații în funcționalități implementate în componente capabile să ruleze ​în mașini virtuale diferite, având un comportament ​vizibil "la distanță"+  * cunoașterea capabilităților oferite de serviciul de nume RMI (rmiregistry) utilizat pentru identificarea obiectelor la distanță într-un mediu distribuit;​ 
 +  * descrierea unui serviciu disponibil la distanță prin definiții de metode ​în cadrul unei interfețe;​ 
 +  * specificarea unei politici de securitate atât pe server cât și pe client pentru a indica drepturile unui cod sursă rezident pe mașina virtuală Java respectivă / transmis prin transferul de comportament; 
 +  * precizarea configurațiilor de rulare necesare pentru lansarea în execuție a serverului și a clientului;​ 
 +  * proiectarea și configurarea serverului care implementează metodele unui obiect la distanță;​ 
 +  * proiectarea și configurarea clientului care invocă metodele unui obiect ​la distanță.
  
 ===== Cuvinte Cheie ==== ===== Cuvinte Cheie ====
Line 13: Line 18:
 ===== Materiale Ajutătoare ====== ===== Materiale Ajutătoare ======
  
 +{{ :​laboratoare:​laborator04:​aipi2014-lab04-slides.pdf }}
 +
 +{{ :​laboratoare:​laborator04:​aipi2014-lab04-slides-3pp.pdf }}
 ===== RMI - aspecte generale ===== ===== RMI - aspecte generale =====
  
Line 106: Line 114:
 ==== Exemplu ==== ==== Exemplu ====
  
-În cele ce urmează, implementarea unei aplicaţii distribuite folosind mecanismul RMI va fi ilustrată pe cazul particular al unui sistem informatic care gestionează locurile rezervate la un restaurant.+În cele ce urmează, implementarea unei aplicaţii distribuite folosind mecanismul RMI va fi ilustrată pe cazul particular al unui serviciu de rezervare a locurilor.
  
-Restaurantul funcţionează după un anumit orar (diferit pentru fiecare dată calendaristică în parte) ​şi dispune de un număr de locuri. Aceste informaţii sunt disponibile în fişierul ''​timetable.txt''​ de pe sever, fiind încărcate la momentul lansării în execuţie a acestuia. În fişier se indică numărul de locuri disponibile,​ precum şi programul de funcţionare pentru fiecare zi în parte, respectând formatul ''​ZZ LL AAAA O1 M1 O2 M2''​ (unde ''​O1:​M1''​ reprezintă momentul de timp de la care se doreşte să se facă rezervarea, iar ''​O2:​M2''​ momentul de timp până la care aceasta este valabilă).+Rezervările pot fi realizate numai în cadrul unui program de funcționare ​(diferit pentru fiecare dată calendaristică în parte), serviciul fiind limitat la un anumit ​număr de locuri. Aceste informaţii sunt disponibile în fişierul ''​timetable.txt''​ din directorul ''​input''​ de pe sever, fiind încărcate la momentul lansării în execuţie a acestuia. În fişier se indică numărul de locuri disponibile,​ precum şi programul de funcţionare pentru fiecare zi în parte, respectând formatul ''​ZZ LL AAAA O1 M1 O2 M2''​ (unde ''​O1:​M1''​ reprezintă momentul de timp de la care se doreşte să se facă rezervarea, iar ''​O2:​M2''​ momentul de timp până la care aceasta este valabilă).
  
 Aplicaţia va avea arhitectura client-server şi are definite semnăturile pentru metodele pe care va trebui să le implementaţi. Aplicaţia va avea arhitectura client-server şi are definite semnăturile pentru metodele pe care va trebui să le implementaţi.
  
-Pe server (''​ReservationServer.java''​) se vor reţine rezervările clienţilor fără a fi necesară asigurarea persistenţei (informaţiile sunt disponibile cât timp serverul rulează, pierzându-se ulterior). Tot aici vor fi implementate metodele din interfaţa pe care o cunoaşte şi clientul, fiind apelate în acest context.+Pe server (''​ReservationImplementation.java''​) se vor reţine rezervările clienţilor fără a fi necesară asigurarea persistenţei (informaţiile sunt disponibile cât timp serverul rulează, pierzându-se ulterior). Tot aici vor fi implementate metodele din interfaţa pe care o cunoaşte şi clientul, fiind apelate în acest context.
  
-Fiecare client (''​ReservationClient.java''​) poate realiza o rezervare specificând o perioadă de timp preferată (orice durată) şi un număr de locuri. Dacă perioada de timp se încadrează în orarul specificat şi în intervalul respectiv există un număr de locuri libere corespunzător cererii făcute, atunci rezervarea este realizată şi locurile respective marcate ca ocupate. Este reţinut totodată şi identificatorul clientului care a realizat rezervarea, astfel încât tot acesta să aibă posibilitatea de a o anula, dacă situaţia o impune. Informaţiile cu privire la rezervările pe care clientul doreşte să le realizeze sunt preluate de la tastatură, respectând acelaşi format ca şi în fişier (dată calendaristică,​ intervalul orar pentru rezervarea respectivă,​ numărul de locuri solicitat), fără a fi necesară dezvoltarea unei interfeţe grafice.+Fiecare client (''​Client.java''​) poate realiza o rezervare specificând o perioadă de timp preferată (orice durată) şi un număr de locuri. Dacă perioada de timp se încadrează în orarul specificat şi în intervalul respectiv există un număr de locuri libere corespunzător cererii făcute, atunci rezervarea este realizată şi locurile respective marcate ca ocupate. Este reţinut totodată şi identificatorul clientului care a realizat rezervarea, astfel încât tot acesta să aibă posibilitatea de a o anula, dacă situaţia o impune. Informaţiile cu privire la rezervările pe care clientul doreşte să le realizeze sunt preluate de la tastatură, respectând acelaşi format ca şi în fişier (dată calendaristică,​ intervalul orar pentru rezervarea respectivă,​ numărul de locuri solicitat), fără a fi necesară dezvoltarea unei interfeţe grafice.
  
 ==== Clase și Interfețe "la distanță"​ ==== ==== Clase și Interfețe "la distanță"​ ====
Line 205: Line 213:
 Obiectele locale sunt transmise prin valoare (este realizată o copie folosind mecanismul de serializare). Sunt copiate toate câmpurile care nu au precizat atributul ''​static''​ sau ''​transient''​. Orice modificare realizată în starea obiectului sunt reflectate doar în copie, dar nu şi în instanţa originală. Similar, schimbările asupra stării obiectului în instanţa originală nu vor fi reflectate în copie. Obiectele locale sunt transmise prin valoare (este realizată o copie folosind mecanismul de serializare). Sunt copiate toate câmpurile care nu au precizat atributul ''​static''​ sau ''​transient''​. Orice modificare realizată în starea obiectului sunt reflectate doar în copie, dar nu şi în instanţa originală. Similar, schimbările asupra stării obiectului în instanţa originală nu vor fi reflectate în copie.
  
-<file java ReservationServer.java> +<file java Server.java>
-import java.rmi.RemoteException;​+
 import java.rmi.registry.LocateRegistry;​ import java.rmi.registry.LocateRegistry;​
 import java.rmi.registry.Registry;​ import java.rmi.registry.Registry;​
 import java.rmi.server.UnicastRemoteObject;​ import java.rmi.server.UnicastRemoteObject;​
-import java.util.ArrayList;​ 
  
-public class ReservationServer implements Reservation ​{+public class Server { 
 + 
 +    public static void main (String[] args) {
     ​     ​
-    ​public ReservationServer() { }+        if (System.getSecurityManager() == null) 
 +            System.setSecurityManager(new SecurityManager());​ 
 + 
 +        try { 
 +            String serviceName = "​ReservationService";​ 
 +            Reservation service = new ReservationImplementation();​ 
 +            Reservation proxy = (Reservation)UnicastRemoteObject.exportObject(service,​ 0); 
 +            Registry registry = LocateRegistry.getRegistry();​ 
 +            registry.rebind(serviceName,​ proxy); 
 +        } catch (Exception exception) { 
 +            System.out.println("​An exception has occurred: "​+exception.getMessage());​ 
 +            if (Constants.DEBUG) 
 +                exception.printStackTrace();​ 
 +        } 
 +    } 
 + 
 +} 
 +</​file>​ 
 + 
 +<file java ReservationImplementation.java>​ 
 +import java.rmi.RemoteException;​ 
 +import java.util.ArrayList;​ 
 + 
 +public class ReservationImplementation implements Reservation { 
 + 
 +    ​public ReservationServer() {  
 +        // ... 
 +    ​}
  
     public ArrayList<​Interval>​ getTimetable() throws RemoteException {     public ArrayList<​Interval>​ getTimetable() throws RemoteException {
Line 230: Line 265:
     public boolean cancelReservation(int customerId, Interval interval) throws RemoteException {     public boolean cancelReservation(int customerId, Interval interval) throws RemoteException {
         // ...         // ...
-    }    ​ 
- 
-    public static void main (String[] args) {        ​ 
-        if (System.getSecurityManager() == null) { 
-            System.setSecurityManager(new SecurityManager());​ 
-        } 
-        try { 
-            String serviceName = "​ReservationService";​ 
-            Reservation service = new ReservationServer();​ 
-            Reservation proxy =  
-            (Reservation)UnicastRemoteObject.exportObject(service,​ 0); 
-            Registry registry = LocateRegistry.getRegistry();​ 
-            registry.rebind(serviceName,​ proxy); 
-        } catch (Exception exception) { } 
     }     }
-}+}   ​
 </​file>​ </​file>​
  
Line 277: Line 298:
  
 <code bash> <code bash>
-$ javac –cp reservation.jar ​ReservationServer.java+$ javac –cp libs/reservation.jar ​Server.java
 </​code>​ </​code>​
   
Line 289: Line 310:
 </​code>​ </​code>​
     * Unix <code bash>     * Unix <code bash>
-# rmiregistry [port] –J-Djava.rmi.server.useCodebaseOnly=false &+$ rmiregistry [port] –J-Djava.rmi.server.useCodebaseOnly=false &
 </​code>​ </​code>​
   * specificarea unei politici de securitate, într-un fişier denumit ''​policy[.txt]'',​ codul sursă obţinând ​ permisiunile de care are nevoie pentru a putea rula: <file policy>   * specificarea unei politici de securitate, într-un fişier denumit ''​policy[.txt]'',​ codul sursă obţinând ​ permisiunile de care are nevoie pentru a putea rula: <file policy>
-grant codebase "file:///<​cale_absoluta>​\\ReservationServer\\-" {+grant codebase "​file://<​cale_absoluta>​/ReservationServer/-" {
     permission java.security.AllPermission;​     permission java.security.AllPermission;​
 }; };
Line 301: Line 322:
 Lansarea în execuţie a serverului se face prin comanda: Lansarea în execuţie a serverului se face prin comanda:
   * Windows <code bash>   * Windows <code bash>
-> java -cp .;​reservation.jar +> java -cp .;libs/reservation.jar 
-       ​-Djava.rmi.server.codebase=file:​///<​cale_absoluta>​\reservation.jar+       ​-Djava.rmi.server.codebase=file://<​cale_absoluta>​/​ReservationServer/​libs/​reservation.jar
        ​-Djava.rmi.server.hostname=localhost        ​-Djava.rmi.server.hostname=localhost
-       ​-Djava.security.policy=policy +       ​-Djava.security.policy=configuration/​policy 
-       ReservationServer+       Server
 </​code>​ </​code>​
   * Linux <code bash>   * Linux <code bash>
-> java -cp .:​reservation.jar +> java -cp .:libs/reservation.jar 
-       ​-Djava.rmi.server.codebase=file:​///<​cale_absoluta>​\reservation.jar+       ​-Djava.rmi.server.codebase=file://<​cale_absoluta>​/​ReservationServer/​libs/​reservation.jar
        ​-Djava.rmi.server.hostname=localhost        ​-Djava.rmi.server.hostname=localhost
-       ​-Djava.security.policy=policy +       ​-Djava.security.policy=configuration/​policy 
-       ReservationServer+       Server
 </​code>​ </​code>​
  
Line 331: Line 352:
   - Se va crea un obiect de tip ''​Interval''​ (eventual din parametrii specificaţi în linia de comandă) şi se vor **apela metodele la distanţă**,​ afişându-se rezultatul.   - Se va crea un obiect de tip ''​Interval''​ (eventual din parametrii specificaţi în linia de comandă) şi se vor **apela metodele la distanţă**,​ afişându-se rezultatul.
  
-<file java ReservationClient.java>+<file java Client.java>
 import java.rmi.registry.LocateRegistry;​ import java.rmi.registry.LocateRegistry;​
 import java.rmi.registry.Registry;​ import java.rmi.registry.Registry;​
  
-public class ReservationClient ​{+public class Client ​{
    
-    public static void main(String[] args) {         +    public static void main(String[] args) {     
-        if (System.getSecurityManager() == null) {+    ​ 
 +        if (System.getSecurityManager() == null)
             System.setSecurityManager(new SecurityManager());​             System.setSecurityManager(new SecurityManager());​
-        } 
   
         try {         try {
Line 352: Line 373:
   
             if (reservation.makeReservation(customerId,​interval,​numberOfSeats)) {             if (reservation.makeReservation(customerId,​interval,​numberOfSeats)) {
-                System.out.println("​succes");+                System.out.println("​The reservation has been made successfully");
             } else {             } else {
-                System.out.println("​insucces");+                System.out.println("​The reservation has not been made successfully");
             }             }
-        } catch (Exception exception) { }+        } catch (Exception exception) {  
 +            System.out.println("​An exception has occurred: "​+exception.getMessage());​ 
 +            if (Constants.DEBUG) 
 +                exception.printStackTrace();​ 
 +        ​}
     }     }
 } }
Line 364: Line 389:
  
 <code bash> <code bash>
-> javac –cp reservation.jar ​ReservationClient.java+$ javac –cp libs/reservation.jar ​Client.java
 </​code>​ </​code>​
  
Line 371: Line 396:
   * lansarea în execuţie a aplicaţiei server ''​ReservationServer'';​   * lansarea în execuţie a aplicaţiei server ''​ReservationServer'';​
   * specificarea unei politici de securitate, într-un fişier numit ''​policy[.txt]'',​ codul sursă obţinând ​ permisiunile de care are nevoie pentru a putea rula: <file policy>   * specificarea unei politici de securitate, într-un fişier numit ''​policy[.txt]'',​ codul sursă obţinând ​ permisiunile de care are nevoie pentru a putea rula: <file policy>
-grant codebase "file:///<​cale_absoluta>​\\ReservationClient\\-" {+grant codebase "​file://<​cale_absoluta>​/ReservationClient/-" {
     permission java.security.AllPermission;​     permission java.security.AllPermission;​
 }; };
Line 378: Line 403:
 Lansarea în execuţie a serverului se face prin comanda: Lansarea în execuţie a serverului se face prin comanda:
   * Windows <code bash>   * Windows <code bash>
-> java -cp .;​reservation.jar +> java -cp .;libs/reservation.jar 
-       ​-Djava.rmi.server.codebase=file:​///<​cale_absoluta>​\ +       ​-Djava.rmi.server.codebase=file://<​cale_absoluta>​/​ReservationClient/​libs/​reservation.jar 
-       ​-Djava.security.policy=policy +       ​-Djava.security.policy=configuration/​policy 
-       ReservationClient ​<adresa>+       Client ​<rmiregistry_IP_address>
 </​code>​ </​code>​
   * Unix <code bash>   * Unix <code bash>
-> java -cp .:​reservation.jar +> java -cp .:libs/reservation.jar 
-       ​-Djava.rmi.server.codebase=file:​///<​cale_absoluta>​\ +       ​-Djava.rmi.server.codebase=file://<​cale_absoluta>​/​ReservationClient/​libs/​reservation.jar 
-       ​-Djava.security.policy=policy +       ​-Djava.security.policy=configuration/​policy 
-       ReservationClient ​<adresa>+       Client ​<rmiregistry_IP_address>
 </​code>​ </​code>​
  
Line 425: Line 450:
  
 <code java> <code java>
-System.setProperty("​java.rmi.server.codebase",​ "file:///​..."​);​+System.setProperty("​java.rmi.server.codebase",​ "​file://​..."​);​
 System.setProperty("​java.security.policy",​ "​configuration/​policy"​);​ System.setProperty("​java.security.policy",​ "​configuration/​policy"​);​
 </​code>​ </​code>​
Line 553: Line 578:
 **8.** [**10 puncte**] Să se verifice comportamentul la distanţă al aplicaţiei,​ apelând metodele implementate de alți colegi. **8.** [**10 puncte**] Să se verifice comportamentul la distanţă al aplicaţiei,​ apelând metodele implementate de alți colegi.
  
-<note tip>Pentru ca serverul implementat de colegii voştri să fie vizibil către clientul cu care doriţi să îl accesaţi, componentele trebuie să aibă adrese IP publice sau să se găsească în aceeaşi reţea de calculatoare în cadrul căreia să aibă adrese IP private din acelaşi spaţiu (mască de reţea / gateway).</​note> ​+Pentru ca serverul implementat de colegii voştri să fie vizibil către clientul cu care doriţi să îl accesaţi, componentele trebuie să aibă adrese IP publice sau să se găsească în aceeaşi reţea de calculatoare în cadrul căreia să aibă adrese IP private din acelaşi spaţiu (mască de reţea / gateway). ​
  
-<​note ​important>Acest exerciţiu nu va fi punctat decât în cadrul laboratorului.</​note>​+<​note>​Acest exerciţiu nu va fi punctat decât în cadrul laboratorului.</​note>​
  
 **9.** [**20 puncte**] Să se implementeze metoda ''​ArrayList<​ReservationInformation>​ getReservation(int clientId)''​ ca fiind apelabilă la distanţă, aceasta întorcând lista cu intervalele în care clientul respectiv are făcute rezervări, precum şi numărul de locuri rezervate în fiecare dintre cazuri. **9.** [**20 puncte**] Să se implementeze metoda ''​ArrayList<​ReservationInformation>​ getReservation(int clientId)''​ ca fiind apelabilă la distanţă, aceasta întorcând lista cu intervalele în care clientul respectiv are făcute rezervări, precum şi numărul de locuri rezervate în fiecare dintre cazuri.
Line 563: Line 588:
 ===== Resurse ====== ===== Resurse ======
  
-[[http://​docs.oracle.com/​javase/​tutorial/​rmi/​index.html|The Java Tutorials - Trail: RMI]]+[[http://​docs.oracle.com/​javase/​tutorial/​rmi/​index.html|The Java Tutorials - Trail: RMI]]\\  
 +[[http://​www.oracle.com/​technetwork/​java/​javase/​tech/​index-jsp-136424.html|Remote Method Invocation Home]]\\  
 +[[http://​www.genady.net/​rmi/​v20/​downloads.html|RMI Plug-in for Eclipse v2.0]]
  
 ===== Soluții ===== ===== Soluții =====
  
-disponibile pe 13 noiembrie+[[https://​github.com/​aipi2014/​Laborator04/​tree/​master/​Eclipse/​|Proiect Eclipse]]\\ 
 +[[https://​github.com/​aipi2014/​Laborator04/​tree/​master/​NetBeans/​|Proiect NetBeans]]
laboratoare/laborator04.1415744291.txt.gz · Last modified: 2014/11/12 00:18 by Andrei Roșu-Cojocaru
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0