Java RMI

Werbung
Überblick
Fernmethodenaufrufe
Remote Method Invocation (RMI)
Aufrufe von Methoden an Objekten auf anderen Rechnern
Remote-Referenz: Transparente Objektreferenz zu entferntem Objekt
Beispiel: Java RMI
Java RMI
Java Remote Method Invocation
Marshalling und Unmarshalling
Aufgabe 1
Client
Server
Stub
Skeleton
RMI-Referenzenschicht
RMI-Transportschicht
VS-Übung (SS11)
Java RMI
1–1
Java RMI
Transportschicht
Datenübertragung zwischen Rechnern
Implementierung
Java RMI – Java Remote Method Invocation
1–2
Java RMI
Referenzenschicht
Verwaltung von Remote-Referenzen
Implementierung der Aufrufsemantik (Beispiele)
Aktueller Standard: Verwendung von TCP/IP-Sockets
Generell: verschiedene Transportmechanismen denkbar
VS-Übung (SS11)
VS-Übung (SS11)
Unicast, Punkt-zu-Punkt
Aufruf an einem replizierten Objekt
Strategien zum Wiederaufbau der Verbindung nach einer Unterbrechung
Client
Server
Client
Server
Stub
Skeleton
Stub
Skeleton
RMI-Referenzenschicht
RMI-Referenzenschicht
RMI-Transportschicht
RMI-Transportschicht
Java RMI – Java Remote Method Invocation
1–3
VS-Übung (SS11)
Java RMI – Java Remote Method Invocation
1–4
Java RMI
Stub & Skeleton
Stub
1.
2.
3.
4.
5.
6.
Java RMI
Remote-Objekt (entferntes Objekt)
erhält einen Objekt-Ausgabe-Strom von der RMI-Referenzenschicht
schreibt die Parameter in diesen Strom
teilt der RMI-Referenzenschicht mit, die Methode aufzurufen
holt einen Objekt-Eingabe-Strom von der RMI-Referenzenschicht
liest das Rückgabe-Objekt aus diesem Strom
liefert das Rückgabe-Objekt an den Aufrufer
Kann aus einer anderen Java Virtual Machine heraus genutzt werden
Erst von außerhalb erreichbar, nachdem es exportiert wurde
Remote-Schnittstelle
Beschreibt die per Fernaufruf erreichbaren Methoden des Objekts
Abgeleitet von java.rmi.Remote (Marker-Schnittstelle)
Einzige Möglichkeit mit Java RMI auf ein entferntes Objekt zuzugreifen
Skeleton
1.
2.
3.
4.
5.
Server
erhält einen Objekt-Eingabe-Strom von der RMI-Referenzenschicht
liest die Parameter aus diesem Strom
ruft die Methode am implementierten Objekt auf
holt einen Objekt-Ausgabe-Strom von der RMI-Referenzenschicht
schreibt das Rückgabe-Objekt in diesen Strom
Client
Server
Stub
Skeleton
Remote-Exception (java.rmi.RemoteException)
Muss im throws-Clause jeder Remote-Methode angegeben sein
Beim Auftreten einer Remote-Exception weiß der Aufrufer nicht, ob die
Methode komplett, teilweise oder gar nicht ausgeführt wurde
RMI-Referenzenschicht
VS-Übung (SS11)
Java RMI – Java Remote Method Invocation
Java RMI
1–5
Registry
Namensdienst
VS-Übung (SS11)
Stub
Skeleton
Java RMI – Java Remote Method Invocation
Java RMI – Beispiel
1–6
Bank-Anwendung
public class VSMoney implements Serializable {
private float amount ;
Registry-Schnittstelle
public VSMoney ( float amount ) {
this . amount = amount ;
}
public interface Registry extends Remote {
public void bind ( String name , Remote obj );
public Remote lookup ( String name );
[...]
}
public float getAmount () { return amount ; }
}
Zuordnung eines Objekts zu einem eindeutigen Namen
Rückgabe der Remote-Referenz zu einem Namen
Konto VSAccount (Remote-Schnittstelle)
Erzeugung und Verbindung zur Registry
public class LocateRe gistry {
public static Registry creat eRegistr y ( int port );
public static Registry getRegistry ( String host , int port );
[...]
}
createRegistry()
getRegistry()
VS-Übung (SS11)
Server
Geldbetrag VSMoney
Bekanntmachen von Remote-Objekten
Abbildung von Objektnamen auf Objektreferenzen
bind()
lookup()
Client
Erzeugung einer Registry auf dem lokalen Rechner
Holen einer Remote-Referenz auf eine Registry
Java RMI – Java Remote Method Invocation
1–7
public interface VSAccount extends Remote {
public void deposit ( VSMoney money ) throws R em oteE x cept io n ;
}
Bank VSBank (Remote-Schnittstelle)
public interface VSBank extends Remote {
public void deposit ( VSMoney money , VSAccount account )
throws R em o te Ex cep ti on ;
}
VS-Übung (SS11)
Java RMI – Java Remote Method Invocation
1–8
Java RMI – Beispiel
Remote-Objekt
Java RMI – Beispiel
Konto-Implementierung VSAccountImpl
VSBankImpl:
Implementierung der Remote-Schnittstelle VSBank
Exportieren des Remote-Objekts
Implementierung der Remote-Schnittstelle VSAccount
Exportieren analog zu VSBankImpl
Synchronisation paralleler deposit()-Aufrufe
Implizit: Unterklasse von java.rmi.server.UnicastRemoteObject
public class VSBankImpl extends U n i c a s t R e m o t e O b je c t
implements VSBank {
// Konstruktor
public VSBankImpl () throws R emot e Ex ception { super (); }
[Auf welchem Rechner erscheint die Bildschirmausgabe?]
// Implementie rung der Remote - Methode
public void deposit ( VSMoney money , VSAccount account )
throws RemoteException {
account . deposit ( money );
}
public class VSAccountImpl implements VSAccount {
private float amount ;
public VSAccountImpl ( float amount ) {
this . amount = amount ;
}
}
VSBank bank = new VSBankImpl ();
public synchronized void deposit ( VSMoney money ) {
amount += money . getAmount ();
System . out . println (" New amount : " + amount );
}
Explizit: Aufruf von UnicastRemoteObject.export()
public class VSBankImpl implements VSBank { [...] }
VSBank b = new VSBankImpl ();
VSBank bank = ( VSBank ) U n i c a s t R e m o t e O b j e c t . exportObject (b , 0);
}
VS-Übung (SS11)
VS-Übung (SS11)
Java RMI – Java Remote Method Invocation
Java RMI – Beispiel
Remote-Objekt
1–9
Server
Server-Implementierung VSBankServer
Java RMI – Java Remote Method Invocation
Java RMI – Beispiel
1 – 10
Client
Client-Implementierung VSBankClient
Erzeugen des Remote-Objekts
Exportieren des Remote-Objekts
Remote-Objekt mittels Registry bekannt machen
public class VSBankClient {
public static void main ( String [] args ) throws Exception {
// Geldbetrag - Objekt anlegen
VSMoney money = new VSMoney (10.0 f );
public class VSBankServer {
public static void main ( String [] args ) throws Exception {
// Remote - Objekt erzeugen
VSBank bankImpl = new VSBankImpl ();
// Account anlegen und exportieren
VSAccount accountImpl = new VSAccountImpl (100.0 f );
VSAccount account = ( VSAccount )
U n i c a s t R e m o t e O b j e c t . exportObject ( accountImpl , 0);
// Remote - Objekt exportieren
VSBank bank = ( VSBank )
U n i c as t R e m o t e O b j e c t . exportObject ( bankImpl , 0);
// Remote - Referenz holen ( Annahme : Server auf faui05a )
Registry registry =
Loca teRegist ry . getRegistry (" faui05a " , 12345);
VSBank bank = ( VSBank ) registry . lookup (" bank ");
// Remote - Objekt bekannt machen
Registry registry =
Loca teRegist ry . cre ateRegi stry (12345);
registry . bind (" bank " , bank );
// Geld einzahlen
bank . deposit ( money , account );
}
System . exit (0);
}
}
}
VS-Übung (SS11)
Java RMI – Java Remote Method Invocation
1 – 11
VS-Übung (SS11)
Java RMI – Java Remote Method Invocation
1 – 12
Java RMI – Beispiel
Interaktion
Ausgangssituation vor Registry-Zugriff des Client
Client Java Virtual Machine
Java RMI – Beispiel
Remote-Referenz auf bank von Registry holen
Server Java Virtual Machine
money
Client Java Virtual Machine
Server Java Virtual Machine
money
account
account
client
VS-Übung (SS11)
Interaktion
bank
Java RMI – Java Remote Method Invocation
client
1 – 13
Java RMI – Beispiel
Interaktion
Methodenaufruf von bank.deposit()
Client Java Virtual Machine
VS-Übung (SS11)
Remote-Referenz
bank
Java RMI – Java Remote Method Invocation
1 – 14
Java RMI – Beispiel
Interaktion
Nach dem Auspacken der Parameter
Server Java Virtual Machine
money
Client Java Virtual Machine
Server Java Virtual Machine
money
Kopie von money
account
account
Rem
o
te-R
efer
enz
bank.deposit()
client
Kopie von money
bank
client
bank.deposit()
bank
Stub für account
VS-Übung (SS11)
Java RMI – Java Remote Method Invocation
1 – 15
VS-Übung (SS11)
Java RMI – Java Remote Method Invocation
1 – 16
Java RMI – Beispiel
Interaktion
Überblick
Methodenaufruf von account.deposit()
Client Java Virtual Machine
Server Java Virtual Machine
money
Java RMI
Java Remote Method Invocation
Marshalling und Unmarshalling
Aufgabe 1
Kopie von money
account
account.deposit()
Kopie von
Kopie von money
client
VS-Übung (SS11)
bank.deposit()
bank
Java RMI – Java Remote Method Invocation
1 – 17
VS-Übung (SS11)
Java RMI – Marshalling und Unmarshalling
Marshalling und Unmarshalling
Unterschiedliche Datentypen
Definition
Primitive Datentypen
Marshalling: Verpacken von Informationen in einer Nachricht
Unmarshalling: Auspacken von Informationen aus einer Nachricht
z. B. char, boolean, int,...
Benutzerdefinierte Datentypen
Problemstellungen
Unterschiedliche Datentypen
Heterogenität bei der lokalen Repräsentation von Datentypen
Unterschiedliche
Parameterübergabearten
Client
1 – 18
z. B. structs
Felder
Server
z. B. int[47]
Referenzen
z. B. char *
Stub
Objekte
Skeleton
z. B. Strings, Dateien,...
...
Kommunikationssystem
Host A
VS-Übung (SS11)
Host B
Java RMI – Marshalling und Unmarshalling
1 – 19
⇒ Kein allgemeines Vorgehen möglich
VS-Übung (SS11)
Java RMI – Marshalling und Unmarshalling
1 – 20
Heterogenität
Heterogenität
Byte Sex“-Problem
”
Kanonische Repräsentation
Big Endian (Network Byte Order)
Nutzung einer allgemeingültigen Form als Zwischenrepräsentation
z. B. IEEE-Standard
⇒ Eventuell unnötige Konvertierungen
Most-significant byte first
z. B. SPARC, Motorola
Little Endian
[z. B. wenn Sender und Empfänger identische Repräsentation nutzen]
Least-significant byte first
z. B. Intel x86
Sender makes it right“
”
Sender kennt Datenrepräsentation des Empfängers
Sender konvertiert Daten
⇒ Multicast an heterogene Gruppe nicht möglich
Repräsentation von Fließkommazahlen
Allgemein
Vorzeichen (s)
Mantisse (m)
Exponent (e)
Zahlenwert: (−1)s ∗ m ∗ 2e
Receiver makes it right“
”
Kennzeichnung des Datenformats
Empfänger konvertiert Daten
⇒ Bereitstellung sämtlicher Konvertierungsroutinen notwendig
Variationsmöglichkeiten
Anzahl der Bits für m und e
Speicherreihenfolge von m, e und s
Byte-Order
VS-Übung (SS11)
Java RMI – Marshalling und Unmarshalling
[Unproblematisch für Byte-Order-Konvertierung]
1 – 21
Unterschiedliche Parameterübergabearten
VS-Übung (SS11)
Java RMI – Marshalling und Unmarshalling
1 – 22
Serialisierung & Deserialisierung in Java
Primitive Datentypen
Eingabeparameter
Hilfsklasse java.nio.ByteBuffer
Teil der Anfragenachricht
z. B. value in void setValue(int value);
public abstract class ByteBuffer [...] {
public static ByteBuffer allocate ( int capacity );
public static ByteBuffer wrap ( byte [] array );
public byte [] array ();
public ByteBuffer put < Datentyp >( < Datentyp > value );
public < Datentyp > get < Datentyp >();
[...]
}
Ausgabeparameter
Teil der Antwortnachricht
z. B. String-Returnwert in String toString();
allocate()
wrap()
array()
put*(),get*()
Ein-/Ausgabeparameter
Teil der Anfrage- und Antwortnachricht
z. B. Stack in Object pop(Stack stack);
neues (leeres) Byte-Array anlegen
bestehendes Byte-Array verwenden
Byte-Array zurückgeben
Daten einfügen bzw. lesen
Beispiel: {S,Des}erialisierung eines double-Werts
Lösungsansatz
double d = 0.47;
ByteBuffer buffer1 = ByteBuffer . allocate ( Double . SIZE / 8);
buffer1 . putDouble ( d );
byte [] byteArray = buffer1 . array ();
ByteBuffer buffer2 = ByteBuffer . wrap ( byteArray );
double d2 = buffer2 . getDouble ();
Semantiken: Call-by-Value, Call-by-Result, Call-by-Value-Result
Behandlung von Referenzen
Zeiger dereferenzieren: Objektkopie erzeugen
Remote-Referenzen
VS-Übung (SS11)
Lösungsvarianten
Java RMI – Marshalling und Unmarshalling
1 – 23
VS-Übung (SS11)
Java RMI – Marshalling und Unmarshalling
1 – 24
Serialisierung & Deserialisierung in Java
Serialisierung & Deserialisierung in Java
Objekte
Schnittstellen
Objekt ⇔ Stream: java.io.Object{Out,In}putStream
Automatisierte {S,Des}erialisierung: java.io.Serializable
public class O bj e ct Ou t pu t S t r e a m [...] {
public O b je ct O u t p u t S t r e a m ( OutputStream out );
public void writeObject ( Object obj ); // Objekt
[...]
// serialisieren
}
public class O bj e c t I n p u tS t r e a m [...] {
public Ob j ec t In pu t S t r e a m ( InputStream in );
public Object readObject (); // Objekt deserialisieren
[...]
}
Muss von jedem Objekt implementiert werden, das von einen
Object{Out,In}putStream serialisiert bzw. deserialisiert werden soll
Marker-Schnittstelle → keine zu implementierenden Methoden
⇒ {S,Des}erialisierung wird vom Object{Out,In}putStream übernommen
Manuelle {S,Des}erialisierung: java.io.Externalizable
Klassenspezifische {S,Des}erialisierung
Stream ⇔ Byte-Array: java.io.ByteArray{Out,In}putStream
public class B y t e A r r a y O u t p u t S t r e a m extends OutputStream {
public byte [] toByteArray (); // Rueckgabe des Byte - Array
[...]
}
public class B y t e A r r a y I n p u t S t r e a m extends InputStream {
public B y t e A r r a y I n p u t S t r e a m ( byte buf []);
[...]
}
VS-Übung (SS11)
Java RMI – Marshalling und Unmarshalling
1 – 25
Serialisierung & Deserialisierung in Java
public interface E xternali zable extends Serializable {
void writeExternal ( ObjectOutput out );
void readExternal ( ObjectInput in );
}
writeExternal()
readExternal()
Objekt serialisieren
Objekt deserialisieren
⇒ {S,Des}erialisierung wird vom Objekt selbst übernommen
VS-Übung (SS11)
Java RMI – Marshalling und Unmarshalling
1 – 26
Überblick
Geschützte Attribute
Einige Attribute einer Klasse sollen nicht serialisiert werden
Sicherheitsaspekte
Effizienzüberlegungen
Einige Objekte können nicht serialisiert & deserialisiert werden,
da sich ihr Zustand nicht so ohne weiteres wiederherstellen lässt
Java RMI
Java Remote Method Invocation
Marshalling und Unmarshalling
Aufgabe 1
FileInputStream
Socket, ServerSocket
Thread
⇒ Schlüsselwort transient
Mit transient gekennzeichnete Attribute werden bei der automatischen
{S,Des}erialisierung vom Object{Out,In}putStream ignoriert
Beispiel
public class Tr an si e n t Ex a m p l e {
private transient Thread t = new Thread ();
}
VS-Übung (SS11)
Java RMI – Marshalling und Unmarshalling
1 – 27
VS-Übung (SS11)
Java RMI – Aufgabe 1
1 – 28
Übungsaufgabe 1
Programmieren mit Java RMI
Beispielanwendung: Schwarzes Brett
Programmieren mit Java RMI
public interface VSBoard {
public void post ( VS BoardMes sage message );
public VSBoar dMessag e [] get ( int n );
public void listen ( V SB oa r dL is te n er listener );
}
Implementierung der Kommunikationsschicht
Client
Server
Stub
public interface VS B oa rd Li s te ne r {
public void newMessage ( VSBoard Message message );
}
post()
get()
listen()
Skeleton
Hinzufügen von neuen Botschaften
Abfragen der neuesten Botschaften
Automatische Benachrichtigung über neue Botschaften
Verteilung mittels Java RMI
Server
Bereitstellung der Anwendung als Remote-Objekt
Registrierung des Diensts bei einer Registry
Kommunikationssystem
Host A
Host B
Client
Zugriff auf den Dienst über Fernaufrufe
Interaktion mit dem Nutzer per Kommandozeile
VS-Übung (SS11)
Java RMI – Aufgabe 1
1 – 29
VS-Übung (SS11)
Java RMI – Aufgabe 1
Implementierung der Kommunikationsschicht
Optimierte {S,Des}erialisierung
Übertragung von Datenpaketen
Ziel
Minimierung der über das Netzwerk zu übertragenden Daten
public class VSConnection {
public void sendChunk ( byte [] chunk );
public byte [] receiveChunk ();
}
Ausgangspunkt
Analyse der vom ObjectOutputStream erzeugten Daten
Beispielklasse
Übermittlung von Daten über eine TCP-Verbindung
Senden und Empfangen von Byte-Arrays beliebiger Länge
public class VSTestMessage implements Serializable {
private int integer ;
private String string ;
private Object [] objects ;
}
Übertragung von Objekten
public class V S O b j e c t C o n n e c t i o n {
public void sendObject ( Serializable object );
public Serializable receiveObject ();
}
Reduzierung der benötigten Datenmenge
Anwendung der Schnittstelle Externalizable
Manuelle Implementierung der {S,Des}erialisierungmethoden
Senden und Empfangen von beliebigen Objekten
Marshalling und Unmarshalling von Nachrichten
VS-Übung (SS11)
Java RMI – Aufgabe 1
1 – 30
1 – 31
VS-Übung (SS11)
Java RMI – Aufgabe 1
1 – 32
Herunterladen