Λειτουργία RMI και Ζητήματα Σχεδίασης Στούμπος Βασίλης

Download Report

Transcript Λειτουργία RMI και Ζητήματα Σχεδίασης Στούμπος Βασίλης

Λειτουργία RMI και
Ζητήματα Σχεδίασης
Στούμπος Βασίλης
[email protected]
Πανεπιστήμιο Αθηνών
Τμήμα Πληροφορικής
Περίληψη
• Crash course σε Java.
• Παράδειγμα σε RMI.
• Ζητήματα σχεδίασης
(κατανεμημένων) εφαρμογών.
– RMI.
– Σχεδιασμός.
Περίληψη - Java
• Crash course σε Java.
– Κλάσεις και αντικείμενα.
– Διαφορές με τη C++.
• Παράδειγμα σε RMI.
• Ζητήματα σχεδίασης
(κατανεμημένων) εφαρμογών.
– RMI.
– Σχεδιασμός.
Κλάσεις στην Java
• Οι κλάσεις (classes)
ορίζουν τύπους
αντικειμένων.
• Τα αντικείμενα
(objects) είναι
στιγμιότυπα
(instances) των
κλάσεων.
• Οι κλάσεις
ομαδοποιούνται σε
μια ιεραρχία πακέτων
(packages).
package gr.uoa.di.stoumpos;
public class Counter {
private int value;
public Counter(int v) {
this.value = v;
}
public int getValue() {
return this.value;
}
public void increment() {
this.value++;
}
}
Αντικείμενα στην Java
• Τα αντικείμενα
(objects) είναι
στιγμιότυπα
(instances) των
κλάσεων.
• Πρόσβαση στα
αντικείμενα μόνο
μέσω αναφορών
(references).
• Πεδία αντικειμένων
και πεδία κλάσεων
(class/object fields).
• Garbage collecting.
Counter a = new Counter(12);
Counter b = new Counter(-12);
for (int i=0; i< 10; i++) {
a.increment();
}
b.increment();
System.out.println(
“Counter a value is ” +
a.getValue());
System.out.println(
“Counter b value is ” +
b.getValue());
Πρόγραμμα Java
• Μία μόνο public
κλάση σε κάθε
αρχείο.
• Όνομα του αρχείου
όπως η public
κλάση.
• Μεταγλώττιση με
javac.
• Εκτέλεση με java.
– Υπάρχει main μέθοδος
κλάσης.
• Ιδεατή Μηχανή (VMVirtual Machine)
/* Αρχείο: TestProg.java */
import gr.uoa.di.stoumpos;
public class TestProg {
public static void main(
String[] args) {
for(i=0; i<args.length; i++){
System.out.println(
“arg[” + i + “]=” +
args[i]);
}
}
Εξαιρέσεις (Exceptions) στη Java
try {
• Η εξαίρεση είναι ένα
αντικείμενο μιας κλάσης.
FileInputStream stream =
• Εξαιρέσεις
new FileInputStream(
χρησιμοποιούνται σε
new File(“foo.dat”));
εξαιρετικές περιπτώσεις.
• Η δυνατότητα εξαίρεσης } catch(FileNotFoundException fnfe)
(throw exception)
// ...
δηλώνεται στις μεθόδους. } catch(SecurityException se) {
// ...
• Διαχείριση λαθών με
} catch(IOException ioe) {
try-catch μπλοκ.
// ...
• Εξαιρέσεις:
– Runtime
– Error
– Άλλες
} catch(Throwable) {
throw new MyException();
} finally {
// ...
}
{
Αντικειμενοστρεφές Μοντέλο
στη Java
• Κληρονομικότητα (inheritance)
– Μόνο απλή (όχι multiple inheritance από C++).
– Χρήση Interface: σαν κλάση χωρίς σώματα μεθόδων
• Πολυμορφισμός (polymorphism)
– Όπως στη C++.
– Strong-typed γλώσσα.
• Ενθυλάκωση (encapsulation)
– Τέσσερα επίπεδα περιορισμών (visibility scope):
private, protected, public και package.
Περίληψη - RMI
• Crash course σε Java.
• Παράδειγμα σε RMI.
– Απλό παράδειγμα.
– Εγκατάσταση συστήματος.
– Ειδικές περιπτώσεις.
• Ζητήματα σχεδίασης (κατανεμημένων)
εφαρμογών.
– RMI.
– Σχεδιασμός.
Τοπική και Απομακρυσμένη
Κλήση Μεθόδου
• Που
βρίσκεται το
αντικείμενο;
• Πως γίνεται
η κλήση;
• Ποιος
αναλαμβάνει
τις
λεπτομέρειες
της κλήσης;
Παράδειγμα RMI
• Τι θα πει απομακρυσμένη κλήση;
– Μια μέθοδος, κάποιου αντικειμένου, καλείται
από κάποια άλλη.
– Διαφορετικός χώρος διευθύνσεων.
– Διαφορετικό μηχάνημα (δίκτυο).
• Τρόπος κλήσης κοινός με τοπική κλήση.
• Διαφοροποιούμε:
– Διεπαφή (interface).
– Υλοποίηση (implementation).
• Θα δούμε τον μετρητή σαν παράδειγμα.
Διεπαφή Μετρητή
• Όλες οι διεπαφές
είναι εξειδικεύσεις
της
java.rmi.Remote
διεπαφής.
• Όλες οι μέθοδοι
μπορεί να δώσουν
RemoteException.
• Το ίδιο interface
πρέπει να
χρησιμοποιεί και ο
καλούμενος και ο
καλών.
import java.rmi.*;
public interface Counter extends
java.rmi.Remote {
public void setValue(int v)
throws RemoteException;
public int getValue()
throws RemoteException;
public void increment()
throws RemoteException;
}
Υλοποίηση Μετρητή
• Η υλοποίηση επεκτείνει
το
java.rmi.UnicastRemot
eObject και υλοποιεί το
Counter.
• Μπορούν να οριστούν
πεδία της υλοποίησης.
• Απαραίτητος default
constructor.
• Οι υλοποιήσεις δεν
επηρεάζονται από το
είδος κλήσης.
import java.rmi.*;
public class CounterImpl extends
java.rmi.UnicastRemoteObject
implements Counter {
int value = 0;
public Counter()
throws RemoteException {
super();
}
public void setValue(int v)
throws RemoteException {
this.value = v;
}
//...
}
Εξυπηρέτης Μετρητή
• Απαιτείται να:
1. Κατασκευαστεί το
αντικείμενο
εξυπηρέτης.
2. Δεσμευθεί ένα
«όνομα» για αυτό.
3. Να συνδεθεί (bind)
με μια διεύθυνση.
import java.rmi.*;
public class CounterServer {
public static void main(
String[] args) {
Counter counter = null;
String url =
“rmi://localhost” +
“:1099/MyNiceCounter”;
try {
counter = new Counter();
Naming.bind(url, counter);
} catch(Exception e) {
System.exit(-1);
}
• Ο εξυπηρέτης τρέχει
συνέχεια.
• Χρειάζεται να τρέχει
το rmiregistry.
}
Απομακρυσμένη Κλήση Μετρητή
• Απαιτείται να:
1. Αναγνωρισθεί το
«όνομα» του
αντικειμένου.
2. Αναφορά στο
απομακρυσμένο
αντικείμενο.
3. Χρήση της αναφοράς.
• Πολλοί πελάτες
εκτελούνται
ταυτόχρονα.
• Χρειάζεται να τρέχει
ο εξυπηρέτης.
Counter counter = null;
String url =
“rmi://localhost” +
":1099/MyNiceCounter”;
try {
counter =
Naming.lookup(url);
counter.increment();
System.out.println(
“Counter a value is ” +
counter.getValue());
} catch(Exception e) {
//...
}
Επίτευξη Απομακρυσμένης
Κλήσης
stub
skeleton
• Λεπτομέρειες της
κλήσης:
– Κώδικας που
γεννιέται
αυτόματα.
– Stubs και
Skeletons.
– Πέρασμα
παραμέτρων και
αποτελεσμάτων.
• Οι διεπαφές έχουν
όλη την πληροφορία.
• Marshalling/Unmarsh
alling.
Εγκατάσταση Συστήματος
• Μεταγλωττίζουμε
όλες τις κλάσεις.
– Χρήση javac.
• Κατασκευάζουμε τον
αυτόματο κώδικα.
– Χρήση rmic.
• Μοιράζουμε κλάσεις
στις τοποθεσίες που
θα χρειαστούν
– jar
• Εκτελούμε (σε
χωριστά shells):
– rmiregistry
– java gr.uoa.di.
stoumpos.CounterServer
– Java gr.uoa.di.
stoumpos.CounterClient
Περίληψη – Σχεδιασμός (RMI)
• Crash course σε Java.
• Παράδειγμα σε RMI.
• Ζητήματα σχεδίασης
(κατανεμημένων) εφαρμογών.
– RMI.
• Εξαιρέσεις.
• Παράμετροι.
– Σχεδιασμός.
Περίληψη – Σχεδιασμός (RMI)
• Crash course σε Java.
• Παράδειγμα σε RMI.
• Ζητήματα σχεδίασης
(κατανεμημένων) εφαρμογών.
– RMI.
• Εξαιρέσεις.
• Παράμετροι.
– Σχεδιασμός.
Πέρασμα Παραμέτρων στο RMI
• Πρωτογενείς Τύποι:
– int, char, double,…
– Αντιγραφή των τιμών.
• Αντικείμενα Java.
• Απομακρυσμένα RMI αντικείμενα.
Πέρασμα Αντικειμένων στο RMI
• Αντικείμενα Java:
– Πρέπει να είναι serializable!
• Υλοποιούν την διεπαφή java.io.Serializable.
• Μεταφορά στιγμιότυπου σε σειρά από bytes.
• Όλα τα μέλη ενός «σειριοποιήσιμου» αντικειμένου
πρέπει να είναι «σειριοποιήσιμα».
• Τα πεδία των κλάσεων δεν λαμβάνονται υπόψη
στη σειριοποίηση.
– Αντιγραφή bytes, και αναδόμηση στον
προορισμό.
– Αντιγραφή ολόκληρων αντικειμένων.
Πέρασμα RMI Αντικειμένων
στο RMI
• Αντικείμενα RMI:
– Στην κατασκευή (constructor) τους τα
αντικείμενα αυτά είναι έτοιμα να
δεχθούν απομακρυσμένη κλήση.
– Δεν έχουν συνδεθεί (bind) με όνομα
πιθανώς.
– Κατασκευή απομακρυσμένων
αναφορών στα αντικείμενα.
– Αντιγραφή αναφοράς.
Διαχείριση Λαθών
• Κάθε φορά που κάτι πάει στραβά έχουμε
εξαίρεση (exception).
• Δύο ειδών εξαιρέσεις:
– Εφαρμογής.
– Συστήματος.
• Επιτρέπεται να έχουμε στην διεπαφή και
εξαιρέσεις εφαρμογής.
– Μήπως είναι καλύτερο να χρησιμοποιήσουμε
wrappers;
– Η κλάση Exception υλοποιεί το Serialized.
– Μία εξαίρεση μπορεί να έχει εμφωλιασμένες
εξαιρέσεις (nested exceptions).
Περίληψη – Σχεδιασμός
• Crash course σε Java.
• Παράδειγμα σε RMI.
• Ζητήματα σχεδίασης (κατανεμημένων)
εφαρμογών.
– RMI.
– Σχεδιασμός.
•
•
•
•
Συγχρονισμός.
Callbacks.
Blocking/Callbacks/Polling.
Push και Pull.
Σχεδιασμός Συγχρονισμού
• Κατασκευάζουμε
ένα αντικείμενο
που κρατά Strings
που φτάνουν σε
αυτό.
• Ζητούμε τα strings
με δείκτες.
• Δεν αφαιρούμε
strings ποτέ.
public interface List {
public void addString(
String s) throws ...;
public String getString(
int i) throws ...;
public int
getNumOfStrings()
throws
RemoteException;
}
Σχεδιασμός Συγχρονισμού (συν.)
• Στην υλοποίηση
κρατούμε τα
strings σε ένα
πίνακα.
• Σίγουρα θα
χάσουμε
strings!
//...
public void addString(
String s) {
if (this.counter) {
throw new Exception(
“No space!”);
}
this.stringArray[
this.counter++] = s;
}
// ...
Σχεδιασμός Συγχρονισμού (συν.)
• Συγχρονίζουμε την
πρόσβαση στον
πόρο (resource).
• Χρησιμοποιούμε
τον synchronized
μηχανισμό της
Java.
• Προσοχή στην
έκταση
συγχρονισμού!
• Προσοχή στο
κοινό σημείο
συγχρονισμού!
//...
public void addString(
String s) {
synchronized(
this.stringArray) {
if (this.counter) {
throw new Exception(
“No space!”);
}
this.stringArray[
this.counter++] = s;
}
}
// ...
Τρόπος Κλήσης
• Όλες οι RMI κλήσεις είναι σύγχρονες
(synchronous/blocking).
– Ο καλούμενος αναστέλλει την εκτέλεσή του
μέχρι να εκτελεστεί η απομακρυσμένη
μέθοδος.
• Μπορούμε να έχουμε κλήση ασύγχρονη;
– Σε επίπεδο σχεδίασης ναι.
– Δύο λύσεις:
• Callbacks
• Polling
Blocking Κλήση
Client
Stub
Skeleton
idle
Server
Callback Κλήση
Client
Callback
Server
create
thread
other
processing
idle
Polling μετά την Κλήση
Client
Request
Server
create
poll
updte
poll
other
processing
thread
Άλλες Τεχνικές
• Push και Pull
• Thread Pools
• Άλλα;
Αναφορές
• Java
– “Thinking in Java”, Bruce Eckel, διαθέσιμο από το
www.bruceeckel.com.
– “The Java Tutorial”, Sun, διαθέσιμο από το
http://java.sun.com/docs/books/tutorial/index.html.
• RMI
– “Fundamentals of RMI”, jGuru, διαθέσιμο (μαζί με άλλα)
από το
http://developer.java.sun.com/developer/onlineTraining/.
• Architecture (πάρα πολλά – ένα όχι τρομερό)
– “Pattern-Oriented Software Architecture”, Douglas C.
Schmidt, διαθέσιμο από (σύνδεσμος powerpoint slides) το
http://www.cs.wustl.edu/~schmidt/POSA/.
• Άλλα
– Το www.google.com είχει πολύ καλά αποτελέσματα όταν
έψαξα.