Marco Ronchetti - [email protected] “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento J0 1 Java Networking Remote Method Invokation “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Object Oriented Paradigm J0 2 invoke method Object 1 Object 2 respond “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Distributed Object Oriented Paradigm J0 3 Client Host/Process invoke method Object 1 Server Host/Process Object 2 respond “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Distributed Object Oriented: implementation J0 4 Local – Client Host/Process Remote Server Host/Process Object 1 “Post Office” Object 2 socket interaction “Post Office” “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Distributed Object Oriented: RMI paradigm J0 5 Local – Client Host/Process RemoteServer Host/Process Object 1 Object 2 magic Ghost of Object 2 (stub) Skeleton of Object 2 “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] CLIENT & SERVER: iCalendar (interface) J0 6 1. Define the common interface import java.rmi.*; public interface iCalendar extends Remote { java.util.Date getDate () throws RemoteException; } “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento SERVER: CalendarImpl Marco Ronchetti - [email protected] import import import import public J0 7 java.util.Date; java.rmi.*; java.rmi.registry.*; java.rmi.server.*; class CalendarImpl 2. Implement the service extends UnicastRemoteObject implements iCalendar { public CalendarImpl() throws RemoteException {} public Date getDate () throws RemoteException { return new Date(); } public static void main(String args[]) { CalendarImpl cal; try { LocateRegistry.createRegistry(1099); cal = new CalendarImpl(); Naming.bind("rmi:///CalendarImpl", cal); System.out.println("Ready for RMI's"); } catch (Exception e) {e.printStackTrace()} } } “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento SERVER: CalendarImpl Marco Ronchetti - [email protected] import import import import public J0 8 java.util.Date; java.rmi.*; java.rmi.registry.*; java.rmi.server.*; class CalendarImpl 3. Create Registry extends UnicastRemoteObject implements iCalendar { public CalendarImpl() throws RemoteException {} public Date getDate () throws RemoteException { return new Date(); } public static void main(String args[]) { CalendarImpl cal; try { LocateRegistry.createRegistry(1099); cal = new CalendarImpl(); Naming.bind("rmi:///CalendarImpl", cal); System.out.println("Ready for RMI's"); } catch (Exception e) {e.printStackTrace()} } } “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento SERVER: CalendarImpl Marco Ronchetti - [email protected] import import import import public J0 9 java.util.Date; java.rmi.*; java.rmi.registry.*; java.rmi.server.*; class CalendarImpl 4. Register yourself extends UnicastRemoteObject implements iCalendar { public CalendarImpl() throws RemoteException {} public Date getDate () throws RemoteException { return new Date(); } public static void main(String args[]) { CalendarImpl cal; try { LocateRegistry.createRegistry(1099); cal = new CalendarImpl(); Naming.bind("rmi:///CalendarImpl", cal); System.out.println("Ready for RMI's"); } catch (Exception e) {e.printStackTrace()} } } “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] CLIENT: CalendarUser J0 10 import java.util.Date; import java.rmi.*; public class CalendarUser { public static void main(String args[]) { long t1=0,t2=0; Date date; iCalendar remoteCal; 6. Use Service try { remoteCal = (iCalendar) Naming.lookup("rmi://HOST/CalendarImpl"); t1 = remoteCal.getDate().getTime(); t2 = remoteCal.getDate().getTime(); } catch (Exception e) {e.printStackTrace();} System.out.println("This RMI call took " + (t2-t1) + “ milliseconds“ ); } } “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Preparing and executing Marco Ronchetti - [email protected] SERVER J0 11 CLIENT C:dir CalendarImpl.java iCalendar.java C:dir CalendarUser.java iCalendar.java C:javac CalendarImpl.java C:rmic CalendarImpl C:dir CalendarImpl.java iCalendar.java CalendarImpl.class iCalendar.class CalendarImpl_Stub.class CalendarImpl_Skel.class C:java CalendarImpl C:javac CalendarUser.java copy C:dir CalendarUser.java iCalendar.java CalendarImpl_Stub.class C:java CalendarUser “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Preparing and executing J0 12 NOTE: in Java 2 the skeleton may not exist (its functionality is absorbed by the class file). In order to use the Java 2 solution, one must specify the switch –v1.2 C:rmic –v1.2 CalendarImpl “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Parameter passing J0 13 Java Standard: void f(int x) : Parameter x is passed by copy void g(Object k) : Parameter k and return value are passed by reference Java RMI: void h(Object k) : Parameter k is passed by copy! UNLESS k is a REMOTE OBJECT (in which case it is passed as a REMOTE REFERENCE, i.e. its stub is copied if needed) “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Alternativa 1 – accensione del registro Marco Ronchetti - [email protected] Invece di scrivere nel codice del server LocateRegistry.createRegistry(1099); è possibile far partire a mano il registro da shell: C: rmiregistry 1099 (port number is optional) Nota: in Java 2 occorre un parametro addizionale: C: rmiregistry –J-Djava.security.policy=registerit.policy dove registerit.policy è un file contenente: grant {permission java.security.AllPermission} o una restrizione dei permessi. Il file è in genere in %USER_HOME%/.java.policy J0 14 “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Alternativa 2 – caricamento dinamico dello stub J0 15 Invece di dover copiare a mano lo stub dal Server al client, si puo’ caricare lo stub automaticamente a runtime? Caric.dinamic o Marco Ronchetti - [email protected] “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento J0 16 import java.util.Date; import java.rmi.*; public class CalendarUser { public static void main(String args[]) { long t1=0,t2=0; Date date; iCalendar remoteCal; System.setSecurityManager(new RMISecurityManager()); try { remoteCal = (iCalendar) Naming.lookup("rmi:/HOST//CalendarImpl"); t1 = remoteCal.getDate().getTime(); t2 = remoteCal.getDate().getTime(); } catch (Exception e) {e.printStackTrace();} System.out.println("This RMI call took " + (t2-t1) + “ milliseconds“ ); } } This client expects a URL in the marshalling stream for the remote object. It will load the stub class for the remote object from the URL in the marshalling stream. Before you can load classes from a non-local source, you need to set a security manager. Note, as an alternative to using the RMISecurityManager, you can create your ownsecurity manager. SERVER: CalendarImpl – Caricamento dinamico “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] import import import import public J0 17 java.util.Date; La prima parte java.rmi.*; java.rmi.registry.*; resta invariata java.rmi.server.*; class CalendarImpl public static void main(String args[]) { extends UnicastRemoteObject CalendarImpl cal; implements iCalendar { System.setSecurityManager(new RMISecurityManager()); public CalendarImpl() throws RemoteException {} System.getProperties().put( public Date getDate () throws RemoteException { "java.rmi.server.codebase", return new Date(); "http://HOST/java/classes/"); } try { LocateRegistry.createRegistry(1099); cal = new CalendarImpl(); Naming.bind("rmi:///CalendarImpl", cal); System.out.println("Ready for RMI's"); } catch (Exception e) {e.printStackTrace()} } } “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Caricamento dinamico (in locale) di una classe remota J0 18 Diverso paradigma: •caricare a runtime una classe residente su una macchina remota, •crearne una istanza locale •ed eseguirla. “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Caricamento dinamico di una classe remota Client Host 3. Invoke Object 1 method 2. Create instance Object 2 Class 2 J0 19 1. Get class Server Host Class 2 “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] La classe remota caricabile dinamicamente J0 20 public interface Executable { public void exec(); } import java.awt.*; public class NetworkApp implements Executable { Frame f; public NetworkApp(Frame f) { this.f = f; }; public void exec() { Label l = new Label("Latest version of your application.", Label.CENTER); f.add("Center",l); f.pack(); f.repaint(); } } “Basi di Dati Web e Distribuite” – Laurea Specialistica in Informatica – Università di Trento Marco Ronchetti - [email protected] Caricatore dinamico J0 21 import java.awt.*; import java.awt.event.*; import java.net.URL; import java.rmi.RMISecurityManager; import java.rmi.server.RMIClassLoader; import java.lang.reflect.*; public class ExecutableLoader { public static void main(String args[]) { System.setSecurityManager(new RMISecurityManager() { public void checkPermission(Permission p){} });; Frame cf = new Frame("NetworkApp"); cf.show(); try { URL url = new URL("http://HOST/java/NetworkApp/"); Class cl = RMIClassLoader.loadClass(url,"NetworkApp"); Class argTypes[] = {Class.forName("java.awt.Frame")}; Object argArray[] = {cf}; Constructor cntr = cl.getConstructor(argTypes); Executable client = (Executable)cntr.newInstance(argArray); client.exec(); } catch (Exception e) {e.printStackTrace();} } }