RMI Teil 3 - auf Matthias

Werbung
Netzprogrammierung:
Java RMI - Remote Method Invocation
(Teil 3)
Robert Tolksdorf und Peter Löhr
Überblick
1. Aktivierung und Deaktivierung von Objekten
http://java.sun.com/javase/6/docs/technotes/guides/rmi/activation/overview.html
Robert Tolksdorf und Peter Löhr
2
Aktivierung und Deaktivierung von Objekten
Robert Tolksdorf und Peter Löhr
Persistente Objekte
Beachte:
Ein fernaufrufbares Objekt braucht als „Träger“ eine aktive JVM
- auch wenn es tagelang nicht aufgerufen wird.
Wünschenswert:
Persistente Objekte: ruhen meistens passiv im Dateispeicher
und sind nur dann in einer JVM aktiv, wenn sie aktuell benutzt
werden.
Für die Benutzung müssen sie aktiviert werden, nach der
Benutzung können sie deaktiviert werden.
Robert Tolksdorf und Peter Löhr
4
Probleme
Naiver Ansatz mit hypothetischem „persistenten Java“:
Wurzelklasse Object verfüge über Methoden save und load
.....
Mytype x, y;
.....
x.save("myob"); .....
// Kopieren in Datei
y = (Mytype) load("myob“);
// Laden aus Datei
..... // Objekt hat normale Klasse: „Persistenzabstraktion“
Probleme:
•
•
•
•
•
Objektidentität
... vor allem bei Benutzung durch mehrere Prozesse
Objektgeflechte (Transaktionen?)
Speicherbereinigung
entfernte Objekte??
Robert Tolksdorf und Peter Löhr
5
Persistenz in Java
Reale Persistenz in Java:
Java Persistence API:
Objektspeicherung in relationalen
Datenbanken mittels EJB 3.0
http://java.sun.com/developer/technicalArticles/J2EE/jpa/
Java RMI Object Activation: Persistente fernaufrufbare Objekte
http://java.sun.com/javase/6/docs/technotes/guides/rmi/activation/overview.html
Robert Tolksdorf und Peter Löhr
6
RMI Activation Framework
• Aktivierung eines entfernten persistenten Objekts erfordert
•
das Hochfahren einer JVM am Ort des Objekts, die als Träger
des aktiven Objekts dient (falls nicht schon vorhanden).
Dies setzt wiederum voraus, dass am Ort des Objekts ein
Prozess installiert ist, der den JVM-Prozess erzeugen kann:
rmid (RMI daemon) ist das einschlägige Programm.
• Der rmid-Prozess verwaltet für jedes lokal aktivierbare Objekt
•
einen Objektdeskriptor (activation descriptor), der die
Lokalisierung von Code und Daten des Objekts erlaubt und
über eine Objektkennung (activation identifier) identifiziert
wird. (ActivationID --> ActivationDesc)
Verzögerte Aktivierung (lazy activation) wird praktiziert:
der Vertreter eines passiven Objekts ist so beschaffen, dass
ein Aufruf nicht direkt zum Objekt, sondern zum RMI daemon
führt. Dieser nimmt die Aktivierung vor und liefert dem
Vertreter die Daten für die Lokalisierung des aktiven Objekts.
Robert Tolksdorf und Peter Löhr
7
Beispiel Counter
Wiederaufnahme des einfachen Beispiels Counter :
package activation;
import java.rmi.*;
interface Counter extends Remote {
int inc(int i) throws RemoteException;
void deactivate() throws Exception; // erlaubt das Deaktivieren
}
package activation;
import java.io.*;
import java.rmi.*;
import java.rmi.activation.*;
class CounterImpl implements Counter {
int c = 0;
public int inc(int i) { return c += i; } // synchronization ignored
.....
Robert Tolksdorf und Peter Löhr
8
Konstruktor für aktivierbare Objekte
// Obligatorischer Konstruktor, bei Aktivierung eingesetzt.
// id und info (hier ein Dateiname) kommen vom rmid.
.....
ActivationID id;
public CounterImpl(ActivationID id, MarshalledObject info) throws ... {
this.id = id;
// memoriert für spätere Deaktivierung
String filename = (String) info.get();
// info-Objekt deserialisieren
c = getState(filename);
// lokale Hilfsmethode
// Objektzustand aus Datei laden - siehe unten
Activatable.exportObject(this, id, 0);
// Objekt über das Aktivierungssystem
// fernaufrufbar machen (vgl. RMI-1, S.21)
}
.....
Robert Tolksdorf und Peter Löhr
9
.....
.....
RandomAccessFile raf;
int getState(String name) throws Exception {
File file = new File(name);
boolean newfile = ! file.exists();
raf = new RandomAccessFile(file, "rw");
return newfile ? 0 : raf.readInt();
}
Nebenbei bemerkt: leider keinerlei Persistenzabstraktion !
Robert Tolksdorf und Peter Löhr
10
Deaktivierung
.....
public void deactivate() throws Exception {
raf.setLength(0);
raf.writeInt(c); // Zustand wird in Datei gerettet
raf.close();
Activatable.unexportObject(this, true );
// Objekt wird beim Fernaufrufsystem abgemeldet
Activatable.inactive(id);
// Objekt wird deaktiviert, ausführende
// JVM wird beendet, falls dort keine weiteren
// aktiven Objekte vorhanden
}
} // end class
Robert Tolksdorf und Peter Löhr
11
... und der Klient
Der Klient wird z.B. mit java activation/Inc mycounter 10
aufgerufen und sieht so aus:
package activation;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Inc {
public static void main(String[] arg) throws Exception {
Registry registry = LocateRegistry.getRegistry();
Counter x = (Counter) registry.lookup(arg[0]);
int i = x.inc(Integer.parseInt(arg[1]));
// impliziert Aktivierung in neuer JVM!
System.out.println("counter is " + i);
x.deactivate(); // deaktiviert x und beendet die JVM
}
}
Robert Tolksdorf und Peter Löhr
12
Einrichten eines aktivierbaren Objekts
• Für die Aktivierung eines Objekts muss eine JVM bereitstehen
•
•
•
•
bzw. bereitgestellt werden.
Für die Konfigurierung dieser JVM müssen geeignete Properties
vorgehalten werden.
Die Konfigurierungsbeschreibung für die JVM wird als
Gruppendeskriptor (activation group descriptor) bezeichnet
(weil eine JVM für eine ganze Gruppe von aktivierbaren
Objekten zuständig sein kann).
Die Gruppendeskriptoren werden vom rmid verwaltet
und dort über Gruppenkennungen (activation group
identifiers) identifiziert (analog zu den Objektkennungen).
Die Einrichtung eines aktivierbaren Objekts erfolgt hier mit
einem separaten Programm Setup, z.B. so:
java ... activation/Setup mycounter activation.CounterImpl count
Optionen
mnemonischer Name
Robert Tolksdorf und Peter Löhr
Objektklasse
Zustandsdatei
13
Einrichten eines aktivierbaren Objekts
package activation;
import java.rmi.*;
import java.rmi.activation.*;
import java.rmi.registry.*;
import java.util.Properties;
public class Setup { // Argumente: Name Klasse Datei (des Objekts)
public static void main(String[] args) throws Exception {
String implClass = args[1];
// Objektklasse
String implBase = System.getProperty("activation.impl.codebase");
// Codebasis der Klasse
.....
Properties props = new Properties(); // für die Objektgruppe
props.put("activation.impl.codebase", implBase);
props.put("activation.file", arg[2]);
props.put("java.security.policy", "group.policy");
props.put("java.class.path", "no_classpath");
Robert Tolksdorf und Peter Löhr
14
Einrichten eines aktivierbaren Objekts
.....
ActivationGroupDesc groupDesc= new ActivationGroupDesc(props, null);
ActivationGroupID groupID = ActivationGroup.getSystem().
registerGroup(groupDesc);
// Gruppe registrieren beim Aktivierungssystem
MarshalledObject data = new MarshalledObject(arg[2]);
ActivationDesc desc = new ActivationDesc(groupID,
implClass, implBase, data);
Remote stub = Activatable.register(desc);
// Objekt registrieren beim Aktivierungssystem
LocateRegistry.getRegistry().rebind(arg[0], stub);
}
// Objekt registrieren beim Registry
} // end class Setup
Robert Tolksdorf und Peter Löhr
15
Richtliniendateien
2 Richtliniendateien werden benötigt:
group.policy: legt fest, was die Objektgruppe darf
grant codeBase "${activation.impl.codebase}" {
// permission to read and write object's file
permission java.io.FilePermission "${activation.file}","read,write";
// permission to listen on an anonymous port
permission java.net.SocketPermission "*:1024-","accept";
// permission to connect to rmid for deactivation
permission java.net.SocketPermission "*:1098", "connect,resolve";
};
Robert Tolksdorf und Peter Löhr
16
Richtliniendateien
rmid.policy
erlaubt dem rmid das Starten von JVMs mit den
angegebenen Properties, wie bei class Setup
vorgesehen:
grant {
// no codebase means any code
permission com.sun.rmi.rmid.ExecOptionPermission
"-Djava.security.policy=${activation.policy}";
permission com.sun.rmi.rmid.ExecOptionPermission
"-Djava.class.path=no_classpath";
permission com.sun.rmi.rmid.ExecOptionPermission
"-Dactivation.impl.codebase=*";
permission com.sun.rmi.rmid.ExecOptionPermission
"-Dactivation.file=*";
};
Robert Tolksdorf und Peter Löhr
17
endlich: der Test
Dateien für lokalen Test mit aktuellem Verzeichnis /home/user/act:
$ ls * | more
group.policy
rmid.policy
activation:
Counter.class
CounterImpl.class
Inc.class
Setup.class
$
Robert Tolksdorf und Peter Löhr
18
endlich: der Test
Lokaler Test mit aktuellem Verzeichnis /home/user/act:
$ rmiregistry &
[1] 6034
$ rmid -J-Djava.security.policy=rmid.policy \
-J-Dactivation.policy=group.policy &
[2] 6035
$ java -Dactivation.impl.codebase=file:/home/user/act/ \
activation/Setup mycounter activation.CounterImpl count
$ java activation/Inc mycounter 5
counter is 5
$ java activation/Inc mycounter 3
counter is 8
$
Robert Tolksdorf und Peter Löhr
19
Zusammenfassung
Robert Tolksdorf und Peter Löhr
Zusammenfassung
• Aktivierbares Objekt
• ist entweder aktiv
• oder passiv, d.h. technisch nicht als Objekt vorhanden,
• kann persistenten Zustand im Dateisystem halten
• rmid
• verwaltet aktivierbare Objekte
• benötigt Richtliniendateien
• rmiregistry registriert aktivierbare Objekte genauso wie
normale Objekte
• (offen geblieben: Speicherbereinigung, Fehlerdetails, ... )
Robert Tolksdorf und Peter Löhr
21
Literatur
http://java.sun.com/javase/6/docs/technotes/guides/rmi/activation/overview.html
Robert Tolksdorf und Peter Löhr
22
Herunterladen