|
Roblet®-Development-Kit 1.2 (22Jul10) API für Anwendungen |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object genRob.genControl.client.Client
Eine Instanz dieser Klasse stellt einen Klienten für einen Roblet®-Server dar.
Die Benutzung dieser Klasse in einer Anwendung ist denkbar einfach (Beispiele weiter unten):
getServer(String)
, so kann man sich eine
Server-Repräsentanz (Server
) geben lassen, die
einen weitergehenden Zugriff auf den Server zuläßt
- insbesondere auf einzelne Fächer (Slot
) eines jeden
Servers.
addListener(NomineeListener)
, so wird man über
die in den Verzeichnissen notierten Roblet®-Server-Kandidaten
informiert.
Dazu muß noch der Verzeichnisdienst
genRob®-genMediator
im Netz laufen.
genRob®-genMediator ist eine Komponente des
genRob®-Systems.
Sieve
) an.
Alle von den Klassen der Bibliothek verwalteten Threads sind Dämonen und haben eine Priorität gleich des Klient-initialisierenden Threads. Allerdings ist es möglich, daß von dieser Bibliothek benutzte fremde Bibliotheken (z.B. RMI) Threads mit anderen Prioritäten und Dämon-Eigenschaften erzeugen.
Vorausgesetzt, daß alle Java™-Archive des RDK insbesondere org.roblet.jar im gleichen Verzeichnis wie DateApp.java liegen, kann mit folgendem kompiliert werden (Unix®/MacOS™/Linux, JDK 6):import genRob.genControl.client.Client; import java.io.Serializable; import java.util.Date; import org.roblet.Roblet; import org.roblet.Robot; // Anwendungsimplementierung public class DateApp { // Methode läuft natürlich lokal als Teil der Anwendung public static void main (String[] args) throws Exception { Client client = new Client (); String servername = "roblet.org"; try { Roblet roblet = new DateRoblet (); Date date = (Date) client. getServer (servername). getSlot (). run (roblet); System.out.println ("Date" + " of " + servername + " is " + date); } catch (Exception e) { e. printStackTrace (); } client. close (); } // Roblet®-Implementierung private static class DateRoblet implements Roblet, Serializable { // Interface Roblet // Methode läuft fern im Server (!) public Object execute (Robot rRobot) { return new Date (); } } }
javac -classpath org.roblet.jar:. DateApp.javaUnd unter Windows™:
javac -classpath org.roblet.jar;. DateApp.javaWill man es nun das Beispiel laufen lassen, gibt man folgendes ein (Unix®/MacOS™/Linux, JDK 6):
java -classpath org.roblet.jar:. DateAppUnd unter Windows™:
java -classpath org.roblet.jar;. DateApp
Diese Anwendung kompiliert man genauso (s.o.). Auch die Ausführung sieht gleich aus. Vor der Ausführung muß allerdings ein Verzeichnis im lokalen Netz laufen (in separatem Terminal; im RDK-Verzeichnis; JDK 6):import genRob.genControl.client.Client; import genRob.genControl.client.Nominee; import genRob.genControl.client.NomineeListener; import java.io.Serializable; import java.util.Date; import org.roblet.Roblet; import org.roblet.Robot; // Anwendungsimplementierung public class DateAppAll { // Methode läuft natürlich lokal als Teil der Anwendung public static void main (String[] args) throws Exception { Client client = new Client (); client. addListener ( new NomineeListener () { public void addedNominee (Nominee nominee) { try { String servername = nominee. toString (); Roblet roblet = new DateRoblet (); Date date = (Date) nominee. getServer (). getSlot (). run (roblet); System.out.println ("Server date" + " of " + servername + " is " + date); } catch (Exception e) { e. printStackTrace (); } } public void removedNominee (Nominee nominee) {} } ); System.out.println ("<Enter> zum Abbrechen"); System.in.read (); client. close (); } // Roblet®-Implementierung private static class DateRoblet implements Roblet, Serializable { // Interface Roblet // Methode läuft fern im Server (!) public Object execute (Robot rRobot) { return new Date (); } } }
java -jar org.roblet.jar directoryAußerdem sollten in diesem Verzeichnis (lokale) Server sichtbar sein bzw. man muß einen Server starten (in separatem Terminal; im RDK-Verzeichnis; JDK 6):
java -jar org.roblet.jar server
Server
,
NomineeListener
Constructor Summary | |
Client()
Erzeugt einen Klienten, wie er normalerweise benötigt wird - dabei wird kein Logging ermöglicht, aber der Zugriff auf Verzeichnisdienste aktiviert. |
|
Client(Log log)
Erzeugt einen Klienten, bei dem das Logging über die mitgegebene Instanz ermöglicht und der Zugriff auf Verzeichnisdienste aktiviert wird. |
|
Client(Log log,
boolean genMediator)
Erzeugt einen Klienten, welcher Log-Informationen generieren und auf Verzeichnisdienste vom Typ genRob®-genMediator zugreifen kann. |
Method Summary | |
void |
addListener(NomineeListener listener)
Fügt einen Interessenten an Roblet®-Server-Kandidaten ( Nominee 's) hinzu. |
void |
close()
Schließt den Klienten und gibt Hilfsressourcen wieder frei. |
protected void |
finalize()
Wird vom "garbage collector" aufgerufen und stellt sicher, für den Klienten sicher, daß close() aufgerufen wird,
nachdem die Instanz nicht mehr referenziert wird. |
Server |
getServer(Identity identity)
Gibt eine Server-Repräsentanz zur angegebenen Identität zur Benutzung zurück. |
Server |
getServer(String servername)
Gibt eine Server-Repräsentanz zum angegebenen Servernamen zur Benutzung zurück. |
void |
removeListener(NomineeListener listener)
Entfernt einen Interessenten an Roblet®-Server-Kandidaten ( Nominee 's). |
Object |
run(String servername,
Roblet roblet)
Deprecated. Zu ersetzen durch eine Kombination von getServer(String) , Server.getSlot()
und Slot.run(Roblet) .
Diese scheinbar einfache Methode ist zwar für Einsteiger
gut, hat aber in der Praxis oft den Blick für ein tieferes
Verständnis der Roblet®-Technik versperrt. |
Methods inherited from class java.lang.Object |
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
public Client() throws ClientException
close()
geschlossen werden, wenn er nicht
mehr benötigt wird.
Ein Aufruf entspricht
Client(null,true)
ClientException
- Fehler beim Erzeugen der RMI-Requisiten
oder Hinzufügen des VerzeichnisdienstesClient(Log,boolean)
public Client(Log log) throws ClientException
close()
geschlossen werden, wenn er nicht
mehr benötigt wird.
Ein Aufruf entspricht
Client(log,true)
log
- Instanz zur Verarbeitung von Log-Informationen
oder null, wenn keine solche Information erzeugt
werden soll
ClientException
- Fehler beim Erzeugen der RMI-Requisiten
oder Hinzufügen des VerzeichnisdienstesClient(Log,boolean)
public Client(Log log, boolean genMediator) throws ClientException
close()
geschlossen werden, um alle verwendeten
Ressourcen wieder freizugeben.
Wird der Zugriff auf Verzeichnisdienst nicht aktiviert, so werden auch keine RMI-Requisiten initialisiert. In diesem Fall können daher keine (alten) Roblet®-Server, die nur per RMI mit den Klienten kommunizieren, vom Klienten benutzt werden.
Beim Zugriff auf Verzeichnisdienste bekommen alle im folgenden von
der Bibliothek intern gestarteten Threads die gleiche Priorität, wie die
des aufrufenden Thread
s.
Ebenso wird die zugehörige ThreadGroup
benutzt, um darin
eine ebensolche mit Namen client#x (x laufende Nummer)
für die zu startenen Threads zu erzeugen.
Für den Zugriff auf Verzeichnisdienste werden einige RMI-Requisiten
initialisiert.
Zu beachten ist, daß RMI seine Threads an anderer Stelle einhängt
und die Prioritäten nach eigenen Regeln setzt.
Alle gestarteten Thread
s des Klienten sind als Dämon
gekennzeichnet;
RMI hier wieder mit Ausnahmen.
Als Teil der RMI-Requisiten wird ein eigener SecurityManager
gesetzt, sofern in der Anwendung noch keiner gesetzt war.
Dieser erlaubt alles.
Wenn das nicht gewünscht ist, so muß vor der Erzeugung
eines Klienten ein eigener SecurityManager
gesetzt werden.
Weiterhin wird zur Unterstützung von RMI ein HTTP-Server gestartet,
der am nächsten freien Port lauscht.
Anfragen werden über den bei Aufruf dieses Konstruktors gesetzten
Kontext-Klassenladers (Thread.getContextClassLoader()
)
befriedigt.
Ist keiner gesetzt, so wird der Klassenlader der Klasse desselben
Thread
s und sofern dieser null ist, der
System-Klassenlader (ClassLoader.getSystemClassLoader()
) eingesetzt.
Für RMI wird passend die Java™-Eigenschaft
java.rmi.server.codebase gesetzt.
log
- Instanz zur Verarbeitung von Log-Informationen
oder null, wenn keine solche Information erzeugt
werden sollgenMediator
- Wenn true wird der Verzeichnisdienst
genRob®-genMediator verwendet, um Roblet®-Server
aufzufinden.
Ansonsten wird der Dienst nicht kontaktiert und gleichzeitig
auch keine RMI-Umgebung initialisiert.
ClientException
- Fehler beim Erzeugen der RMI-Requisiten
oder Hinzufügen des VerzeichnisdienstesClient()
Method Detail |
public void close()
Ein mehrfacher Aufruf dieser Methode ist ungefährlich.
Schließt man den Klienten nicht, so endet die JVM solange nicht,
bis explizit ein Aufruf von System.exit(int)
erfolgt.
finalize()
public Object run(String servername, Roblet roblet) throws InterruptedException, ClientException, Exception
getServer(String)
, Server.getSlot()
und Slot.run(Roblet)
.
Diese scheinbar einfache Methode ist zwar für Einsteiger
gut, hat aber in der Praxis oft den Blick für ein tieferes
Verständnis der Roblet®-Technik versperrt.
Zur Ausführung wird ein neues Fach auf dem Server eingerichtet
und das Roblet® kommt darin zum Laufen
- dessen Ausführung
beendet also keine Roblets® aus früheren Aufrufen
dieser Methode (anders als bei Slot.run(Roblet)
).
Das Roblet® wird für den Transport serialisiert
und zum Server geschickt.
Aus diesem Grund muß das Roblet den Typ
Serializable
implementierten.
Wird statt eines Roblets® null übergeben,
so wird auch null zurückgegeben.
Es wird kein Roblet beendet, da sowieso ein neues Fach
für null benutzt würde (anders als bei Slot.run(Roblet)
).
Ist das Roblet® nicht null, so wird vom
Roblet®-Server dessen Methode
Roblet.execute(org.roblet.Robot)
ausgeführt.
Nach deren Ende wird ihr Rückgabewert hier zurückgegeben.
Es wird kein Roblet beendet, da sowieso ein neues Fach
für null benutzt würde (anders als bei Slot.run(Roblet)
).
Wird im Hauptthread, welcher Roblet.execute(org.roblet.Robot)
ausführt, eine Ausnahme, abgeleitet von Exception
,
geworfen, so wird sie an dieser Stelle auch geworfen.
Schließt man diese Methode demnach in einen
try-Block ein, so kann man im catch-Block
direkt die selbst erzeugten Ausnahmen abfangen.
Wurde eine Ausnahme, abgeleitet von Exception
,
in einem beliebigen anderen Thread des Roblets® erzeugt
(und nicht abgefangen) während der Hauptthread
des Roblets® noch lief, so wird auch diese entsprechend hier geworfen
(während das Roblet® bereits vom Server beendet wurde).
Entsteht im Hauptthread oder einem beliebigen anderen eine
Ausnahme, welche nicht von Exception
abgeleitet ist,
so wird der Server nach Möglichkeit trotzdem Informationen
schicken, die vom Roblet®-Klienten dann jedoch
in eine ClientException
gepackt werden.
Sollte die Verbindung unbrauchbar werden, so wird
eine ClientException
geworfen.
Es bleibt in diesem Fall offen, ob das Roblet® erfolgreich ankam und
lief oder nicht.
Ein erneuter Aufruf der Methode baut eine neue Verbindung auf
und hat keinen Bezug zu vorhergehenden Aufrufen.
Wird der diese Methode aufrufende Thread unterbrochen,
so wird entweder eine Ausnahme vom Typ InterruptedException
geworfen oder das Unterbrechungssignal (interrupt flag)
des Threads gesetzt.
Ersteres wird gemacht, wenn die Netzwerkaktivität noch nicht oder
gerade ausgelöst wurde.
Letzteres geschieht, wenn die Aktivität bereits abgeschlossen
ist.
Im letzteren Fall sind die Ergebnisse zwar normal verwendbar, aber
es ist auch zu beachten, daß der Thread natürlich beim nächsten
Object.wait()
, Thread.sleep(long)
o.ä. eine Ausnahme
obigen Typs erzeugen wird.
Mehrmalige Aufrufe dieser Methode mit den gleichen Parametern kann in bestimmten Fällen verschiedene Server ansprechen. Gründe dafür können Load-Balancer und Änderungen im DNS sein, welches andere Server sichtbar werden läßt.
Anfragen nach Klassen und Ressourcen für bzw. durch das Roblet®
werden über den bei Aufruf dieser Methode gesetzten
Kontext-Klassenladers (Thread.getContextClassLoader()
)
befriedigt.
Ist keiner gesetzt, so wird der Klassenlader der Klasse des Roblets®
verwendet.
Ist dieser null, so wird der der Klasse des diese Methode
aufrufenden Thread
s benutzt.
Ist auch dieser null, so wird der System-Klassenlader
(ClassLoader.getSystemClassLoader()
) eingesetzt.
servername
- Name des Roblet®-Servers in der Form host:port,
wobei host ein DNS-Name oder direkt eine
IP-Adresse sein kann und
port im Bereich von 1
bis 65535 liegen mußroblet
- Roblet®, welches auf dem Server zum Laufen
gebracht wird
InterruptedException
- falls der aufrufende Thread
beim Warten auf das Resultat durch die Anwendung
zum Unterbrechen aufgefordert wird oder bereits
vorher sein Unterbrechungssignal (interrupt flag)
gesetzt war
ClientException
- falls die Verbindung nicht funktioniert,
der Servername eine inkorrekte Syntax hat
oder sonstige Probleme auftraten
- verkettet ist die Ursache
Exception
- falls im Roblet® ein Fehler auftratgetServer(String)
,
getServer(Identity)
,
addListener(NomineeListener)
public Server getServer(String servername) throws InterruptedException, ClientException
Es wird eine Verbindung zum Roblet®-Server aufgebaut,
um dessen Identität festzustellen,
da möglicherweise bereits eine Verbindung unter einem anderen
Namen besteht.
Ist letzteres der Fall, so wird die bereits bekannte Repräsentanz
zurückgegeben.
Pro Klient (Client
) wird für einen Server
immer die gleiche Repräsentanz (Instanz) zurückgegeben.
Man kann also bei Bedarf direkt auf Gleichheit prüfen.
Mehrmalige Aufrufe dieser Methode kann in bestimmten Fällen die Rückgabe verschiedener Server-Repräsentanzen zur Folge haben. Gründe dafür können Load-Balancer und Änderungen im DNS sein, welches andere Server sichtbar werden läßt.
servername
- Name des Roblet®-Servers in der Form host:port
oder host,
wobei host ein DNS-Name oder direkt eine
IP-Adresse sein kann und
port im Bereich von 1
bis 65535 liegen muß;
ohne Port-Angabe wird Standard-Port 2001 angenommen
InterruptedException
- falls der aufrufende Thread
beim Warten auf den Roblet®-Server durch die Anwendung
zum Unterbrechen aufgefordert wird oder bereits
vorher sein Unterbrechungssignal (interrupt flag)
gesetzt war
ClientException
- falls der Servername eine inkorrekte Syntax
hat oder sonstige Probleme auftraten
- verkettet ist die UrsachegetServer(Identity)
,
run(String,Roblet)
,
addListener(NomineeListener)
public Server getServer(Identity identity) throws InterruptedException, ClientException
Es wird eine Verbindung zum Roblet®-Server aufgebaut,
um dessen Identität festzustellen,
da möglicherweise bereits eine Verbindung unter einem anderen
Namen besteht.
Ist letzteres der Fall, so wird die bereits bekannte Repräsentanz
zurückgegeben.
Pro Klient (Client
) wird für einen Server
immer die gleiche Repräsentanz (Instanz) zurückgegeben.
Man kann also bei Bedarf direkt auf Gleichheit prüfen.
identity
- Identität des Roblet®-Servers
InterruptedException
- falls der aufrufende Thread
beim Warten auf den Roblet®-Server durch die Anwendung
zum Unterbrechen aufgefordert wird oder bereits
vorher sein Unterbrechungssignal (interrupt flag)
gesetzt war
ClientException
- falls sonstige Probleme auftraten
- verkettet ist die UrsachegetServer(String)
,
run(String,Roblet)
,
addListener(NomineeListener)
public void addListener(NomineeListener listener)
Nominee
's) hinzu.
Dieser Interessent wird über alle bereits gefundenen und zukünftige
Server-Kandidaten informiert.
listener
- Interessent an Roblet®-Server-KandidatenremoveListener(NomineeListener)
,
getServer(String)
,
run(String,Roblet)
public void removeListener(NomineeListener listener)
Nominee
's).
Fortan erhält er keine Informationen mehr.
Ist der angegebene Interessent gar nicht eingemeldet gewesen, so passiert nichts.
listener
- Interessent an Roblet®-Server-KandidatenaddListener(NomineeListener)
protected void finalize()
close()
aufgerufen wird,
nachdem die Instanz nicht mehr referenziert wird.
|
Roblet®-Development-Kit 1.2 (22Jul10) API für Anwendungen |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |