Distribuerade system Java XII - 1 CORBA eller RMI Java XII - 2 Några motiv till distribuerade system kan vara att: Utjämna belastningen mellan olika maskiner i ett nätverk Utnyttja kapaciteten i en större dator vid tunga beräkningar Befrämja enklare systemkonstruktioner Det traditionella sättet distribuera data över ett nätvek till andra maskiner för bearbetning leder ofta till komplicerade och svårbegripliga lösningar Ett effektivt sätt att angripa denna typ av problem är att tillämpa strukturer som tillåter anrop av metoder till objekt som existerar på på andra maskiner i nätverket CORBA och RMI är två vanliga metoder som stöder distribuerade systemlösningar CORBA är en förkortning av Common Object Request Broker Architecture RMI är en förkortning av Remote Method Invocation I Java finns stöd för både CORBA och RMI Systemlösningar i CORBA och RMI bygger på ungefär liknande ideér men CORBA leder till mera komplicerade strukturer Skillnaden mellan RMI och CORBA är att den senare gör det möjligt att knyta samman delar av ett system utvecklade i olika programspråk RMI tillåter endast distribuerade lösningar som är helt och hållna skrivna Java. 1
Remote interfaces Java XII - 3 RMI arkitekturen Java XII - 4 Kommunikationen mellan klient och server sker över gemensamma interfaces. På servern förekommer den klass som implementerar gränssnittet Klienten anropar de metoder som förekommer i serverns klass via gränssnittet. Klient Interface A Metod a Metod b Server Interface A Klass B Metod a Metod b Klient Server Stub Skeleton Interface A Metod a Metod b Interface A Klass B Metod a Metod b -------------Remote Reference Layer------------ Transport Transport Elektriska signaler 2
Java XII - 5 En klass vars metod vi vill använda The remote interface Java XII - 6 public class PerfectTime public long getperfecttime() return System.currentTimeMillis(); public static void main(string[] args) PerfectTime pt = new PerfectTime(); System.out.println( Tid: + pt.getperfecttime()); På Servern finns denna klass Ett antal klienter vill synkronisera sin tid mot Serverns tid Klienterna kan anropa metoden getperfecttime() via det gemensamma gränssnittet TimeInterface public interface TimeInterface long getperfecttime() throws RemoteException; Serverns klass PerfectTime måste implementera gränssnittet TimeInterface public class PerfectTime implements TimeInterface public long getperfecttime() return System.currentTimeMillis(); Detta kan åstadkommas genom att klienterna via den överförda referensen till objektet pt anropar dess metod getperfecttime(). public static void main(string[] args) PerfectTime pt = new PerfectTime(); System.out.println( Tid: + pt.getperfecttime()); 3
Java XII - 7 Anpassning av the remote interface till RMI Anpassning av klassen som implementerar the remote interface, del 1 Java XII - 8 The remote interface måste vara public The remote interface måste ärva av klassen Remote Varje metod i the remote interface måste deklarera att den kan kasta ett RemoteException Parametrar i metodernas parameterlistor som är objekt överförs som värden. Därför måste dessa objekt implementera gänssnittet Serializable Hur detta går till är beskrivet på sidorna 548-549 i Hans-Erik Erikssons bok Programutveckling med Java import java.rmi.*; public interface TimeInterface extends Remote long getperfecttime() throws RemoteException; Klassen PerfectTime måste ärva från klassen UnicastRemoteObject Klassens konstruktor måste defineras explicit även om den inte gör något. Detta på grund av att den måste kunna kasta ett undantaget av typen RemoteException import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.*; import java.net.*; public class PerfectTime extends UnicastRemoteObject implements TimeInterface public PerfectTime() throws RemoteException public long getperfecttime() throws RemoteException return System.currentTimeMillis(); 4
Anpassning av klassen som implementerar the remote interface, del 2 Java XII - 9 Skapa stub och skeleton Java XII - 10 public static void main(string[] args) System.setSecurityManager(new RMISecurityManager()); try PerfectTime pt = new PerfectTime(); Naming.bind( rmi://pc-hem.du.se:4711/time", pt); System.out.println("Ready to do time"); catch (Exception e) System.out.println(e); Metoden main hanterar alla detaljer för att registrera objektet pt i Servern enligt följande. Skapar och installerar en security manager som stöder RMI Skapar objektet Registrerar objektet i rmirigistry. Observera att localhost inte fungerar under Java 1.1. Använd istället datorns riktiga adress. Nu är det dags att kompilera the remote interface och klassen PerfectTime. Det görs på vanligt sätt med hjälp av javac Därefter så ska stub och skeleton skapas. Detta görs med hjälp av en speciell RMIkompilator. Den kallas för rmic. När man skapar stub och skeleton är det viktigt att man står i den katalog som innehåller den intressanta klassen, det här fallet PerfectTime. G:\server> javac TimeInterface.java G:\server> javac PerfectTime.java G:\server> rmic PerfectTime Nu ska följande filer ha skapats: TimeInterface.class PerfectTime.class PerfectTime_Stub.class PerfectTime_Skel.class 5
Klienten Java XII - 11 Klienten klass Java XII - 12 På klienten så finns den klass vars objekt kommer att utnyttja metoden getperfecttime borta på Servern. Därför måste the remote interface klass-fil kopieras äver till Klienten. I det här fallet är det filen TimeInterface.class. Likaså måste stub -filen kopieras över Klienten. Anpassningen av Klientens klass består i att hämta en refens till objektet som finns borta på Servern. Detta görs med på följande sätt: TimeInterface tid = (TimeInterface)Naming.lookup( rmi://pc-hem.du.se:4711/time ); Dessutom måste en securitymanager skapas och installeras. import java.rmi.*; import java.rmi.registry.*; public class DisplayPerfectTime public static void main(string[] args) System.setSecurityManager(new RMISecurityManager()); try TimeInterface tid = (TimeInterface)Naming.lookup( "rmi://pc-hem.du.se:4711/time"); // Från och med nu kan objektet och dess metod användas på // det vanliga sättet! for (int i=0; i<10; i++) System.out.println("perfect time = " + tid.getperfecttime()); catch (Exception e) System.out.println("Fel i klienten: " + e); Klassen kompileras på vanligt sätt G:\klient> javac DisplayPerfectTime.java 6
Starta Server och Klient Java XII - 13 Anpassning till JDK 1.2 Java XII - 14 Serversidan måste vara uppe innan klientens program går att köra Den nya versionen av Java 1.2 har en strängare säkerhetskontroll än tidigare versioner. Först måste programmet rmiregistry startas med rätt portnummer. Därefter kan Java applikationen PerfectTime köras i gång Därför måste man skriva ett egen säkerhetspolicy. Ett exempel på hur en sådan fil kan se ut följer här: G:\server> start rmiregistry 4711 G:\server> start java PerfectTime I och med att Serversidan är klar så kan Javaprogrammet på Klienten startas G:\klient> start java PerfectTime grant // Allow everything for now permission java.security.allpermission; ; Att använda ovanstående policy i en verklig tillämpning är inte att rekommendera eftersom den tillåter allt! I det här exemplet så heter filen som innehåller ovanstående säkerhetspolicy policy och det finns en kopia på både Server och klient. Programmen startas enligt följande G:\server> start rmiregistry 4711 G:\server> start java -Djava.security.policy=policy PerfectTime G:\Klient> java -Djava.security.policy=policy DisplayPerfectTime 7
Ett resultat från klientprogrammet Java XII - 15 G:\java\rmi\klient>java -Djava.security.policy=policy DisplayPerfectTime perfect time = 920500144340 perfect time = 920500144390 perfect time = 920500144390 perfect time = 920500144440 perfect time = 920500144440 perfect time = 920500144440 perfect time = 920500144500 perfect time = 920500144500 perfect time = 920500144500 perfect time = 920500144500 G:\java\rmi\klient> 8