Inhaltsverzeichnis - Einleitung…………………………………….2 - Übersicht……………………………………..3 - Server………………………………………...4-16 o Programm Engine………………………………4 Control Server……………….. …….5 Broadcast………………...................6 Messenger Core……………....…….7 Startup………………………………8 Update………………………………9 o GUI Systemtray………………….............10 Menü………………………………..11 About & Update ………....................11-12 Terminal…………………….............13 GroupLayout………………………..14-15 Messenger…………………………..16 - Client…………………………………………17-18 1 Einleitung Superior baut auf das in Java vorhandene RMI (= Remote Method Invocation) System auf. Mehr Informationen dazu können unter http://java.sun.com/javase/technologies/core/basic/rmi/index.jsp gefunden werden. Aller Anfang ist schwer, doch in diesem Fall war er beinahe unmöglich. Jedes Tutorial das im Internet zu RMI gefunden werden kann, funktioniert nicht. Das liegt teilweise daran das sich seit dem neuen Update vieles verändert hat, anderseits auch daran das es einfach nicht ausgereift genug ist. Wie diese Schwierigkeiten überwunden werden konnte und welche Tricks angewendet wurden wird in dieser Dokumentation Schritt für Schritt gezeigt. Nachfolgendend noch eine kurze Übersicht was Superior kann: Alle Rechner eines Netzwerkes in weniger als einer Sekunde ausfindig machen Berechnungen durchführen die erst zur Laufzeit bekannt werden. Client flexibel im Netzwerk positionieren Einfache Bedienung (Nur eine Zeile mehr Code aufwand pro Befehl) Jederzeit erweiterbar Update fähig Mit allen Systemen kompatibel Servergröße unter 50kbyte Und noch vieles mehr! Für zusätzliche Informationen wie neue Updates und News kann auch die Website benjaminschagerl.com aufgesucht werden. 2 Übersicht Theoretisch unendlich viele Server. Update Messenger Terminal Systemtray Startup GUI CONSOLE Server (ENGINE) Messenger Core Broadcast Server RMI Registry Control Server Broadcast IP (230.0.0.1) Client Server Manager Execute Superior Client 3 Server Engine Die Engine kann als Kernstück betrachtet werden. Darum wurde sie auch als erstes entwickelt. Als Grundlage dazu wurde das Tutorial von Sun über RMI verwendet. Wie bereits in der Einleitung erwähnt funktionierte es allerdings nicht. Das erste große Hindernis waren die Sicherheitsbestimmungen von RMI. Demnach dürfen Methoden auf einen anderen PC nur aufgerufen werden, wenn diese, die richtigen Berechtigungen für die Anwendung besitzen. Grundsätzlich kein Problem, denn diese können einfach manuell vom jeweiligen Benutzer gesetzt werden. Jedoch widerspricht dies vollkommen dem Prinzip von Superior: einfach und schnell, beliebig viele Server zu starten und zu benützen. Deswegen wurde eine Methode entwickelt die eine mitgelieferte „.policy“ Datei zur Laufzeit lädt und die nötigen Berechtigungen setzt. void setPolicy() { URL url = ClassLoader.getSystemClassLoader().getResource("Superior.policy"); System.setProperty("java.security.policy", url.toString()); } Der Trick dabei ist zuerst die Sicherheitseinstellungen von Java zu ändern und danach mit System.setSecurityManager(new RMISecurityManager()); einen neuen Security Manager zu setzen. Dieser lädt dann die eben neu gesetzten Sicherheitsbestimmungen und nimmt diese als richtig an. Ein weiteres Problem ist die RMI Registry. Diese wird benötigt um über den Server Methoden aufzurufen. Im Internet findet man nur den Registry Start über einen Parameter im Konsolenaufruf. Erst nach vielen verschiedenen Versuchen wurde eine Möglichkeit gefunden dies im Programm über eine Methode zu erledigen. LocateRegistry.createRegistry(Registry.REGISTRY_PORT); Die weitere Besonderheit der Engine ist, dass jeder Methodenaufruf (vorausgesetzt die Klasse ist Serializeable) ausgeführt werden kann. Dies wird mit „Generics“ gelöst: public <T> T executeTask(Task<T> t) { return t.execute(); } 4 Control Server Ursprünglich wurde der Control Server eingeführt um dynamische Clients zu ermöglichen. Sobald sich der Client mit dem Server verbindet schickt er die neue „Codebase“ mit. Der Server aktualisiert diese sofort und kann nun Methoden von dieser aufrufen. Das Problem an dieser Sache war das es bis dato keine Möglichkeit gab die Codebase zur Laufzeit zu ändern. Lediglich beim Starten über die Kommandokonsole kann diese für die Anwendung mitgegeben werden. Die Lösung: Class[] parameters = new Class[]{URL.class}; URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader(); Class<?> sysclass = URLClassLoader.class; Method method = sysclass.getDeclaredMethod("addURL",parameters); method.setAccessible(true); method.invoke(sysloader,new Object[]{u}); Nach Aufruf dieser Methode ist nun der übergebene URL (link zur neuen Codebase) in die laufende Anwendung integriert und er wird vom Java ClassLoader verwendet. Durch den immer größer werdenden Server wurde der Control Server auch noch mit anderen Funktionen erweitert. Zur grundlegenden Kontrolle wurden nachfolgende Befehle integriert: closeConnection - beendet sauber die Verbindung zum Server getPerformance - übermittelt an den Client die Performance des Servers shutdownControlServer & shutdownServer – beendet den jeweiligen Task Später wurde dann auch die Abwicklung der Messenger Initialisierung, aus logischen Gründen über den Control Server abgewickelt. Da RMI nicht die Möglichkeit besitzt den derzeitigen Stand der Kalkulation wiederzugeben wurde außerdem eine Routine eingeführt die dem jeweiligen Server mitteilt welche Methode ausgeführt wird und wann diese beendet wird. Zusammenfassend kann man sagen dass nun alle Anfragen vom Client zum Server über den Control Server abgewickelt werden. Dies hat den Vorteil, dass nur vorher definierte Befehle, richtig ausgeführt werden und die anderen bereits verworfen werden, bevor sie den Server erreichen. Die einzige Ausnahme bildet hier die eigentliche Kernfunktion von Superior: der Methodenaufruf. Dieser wird ohne Zwischeninstanz direkt von der RMI Registry (die über den Client angesprochen wird) an den Server geleitet um ein schnellstmögliche Abhandlung zu gewährleisten. 5 Broadcast Server Erst durch den Broadcast Server wurde es möglich alle Computer in einem Netzwerk zu finden. Denn zuerst wurde das durch eine Methode des Clients versucht. Erste Überlegung: Es wird zu jeder möglichen IP – Adresse eine Socket Verbindung aufgebaut. Je nachdem ob diese zustande kommt oder nicht kann dann erkannt werden ob sich dort ein Server befindet. Socket s = new Socket (IP, PORT); Theoretisch ist dies zwar so möglich jedoch entsteht ein großes Zeitproblem. Die Dauer pro Erkennen eines PC beträgt bis zu 5 Minuten! Verbesserung: Es gibt in Java die Möglichkeit die Zeit anzugeben, die einer Verbindung gegeben wird bevor angenommen wird das der PC nicht existiert. Socket s = new Socket(); s .connect(new InetSocketAddress(IP,PORT),100); Wobei die rote Zahl angibt wie viele Millisekunden maximal gewartet werden, kommt dann keine Antwort von dem jeweiligen PC wird angenommen, das er nicht existiert. Die ersten Tests mit dieser Art verliefen ganz gut. Jedoch stellte sich heraus das das schnelle Auf- und Abbauen eines Socket auf Dauer nicht möglich ist. Das OS gibt den Speicher viel zu langsam wieder frei und somit wird relativ schnell die maximale Socketanzahl erreicht. Die Lösung: Erst durch einen komplett neuen Ansatz wurde es schließlich möglich alle Server zu finden. Es wird jetzt nicht mehr auf eine Verbindung vom Client gewartet sondern, eine bestimmte Broadcast-IP (in unserem Fall 230.0.0.1) auf Nachrichten überprüft. Das hat den großen Vorteil dass der Client lediglich einen Befehl auf der Broadcast-IP versenden muss und dann sofort alle Server angesprochen werden. Bekommt nun ein Server die Nachricht meldet sich dieser bei dem Client und nicht wie in den anderen Versuchen umgekehrt. Die IP-Adresse des Clients findet der Server übrigens über das Nachrichtenpaket des Clients heraus, da dieses die Quelladresse beinhaltet. Nun muss der Client nach versenden des Broadcasts nur noch auf alle eingehenden Verbindungen warten und kennt somit alle Server im Netzwerk. Nachrichten einer Broadcast-IP empfangen: DatagramPacket in = new DatagramPacket(byteBuffer, byteBuffer.length); MulticastSocket mcsocket = new MulticastSocket(BPORT); InetAdress group = InetAddress.getByName(BROADCAST_IP); mcsocket.joinGroup(group); mcsocket.receive(in); 6 Messenger Core Ein Messenger wurde eigentlich nur entwickelt da die vorhandene Systemstruktur geradezu ideal für eine solche Anwendung ist. Außerdem soll er zeigen dass der Superior Server jederzeit mit geringem Aufwand um nützliche Funktionen erweitert werden kann. Deswegen wurde vor allem darauf geachtet das dieser kompakt, einfach zu bedienen und stabil ist. Gleichzeitigt wurde er mit allen nötigen Grundfunktionen ausgestattet. Der Messenger Core bietet der dem Messenger GUI alle nötigen Methoden wie z.B.: connect() oder sendMessage(String msg) Dabei wurde das verbinden zwischen zwei Server sehr interessant gelöst. Es wurde bewusst auf einen weiteren Thread der auf eingehende Verbindungen wartet verzichtet (aus Performancegründen). Deshalb wird die Verbindung über den Control Server folgendermaßen realisiert: Sobald sich ein Messenger mit dem anderen verbinden will, schickt er eine Nachricht an den Control Server des Zielrechners. Gleichzeitig wird am Server ein SocketServer erstellt der auf die eingehende Verbindung wartet. Der Zielrechner bekommt nun die Information vom Control Server dass ein anderer Server mit ihm kommunizieren möchte. Somit verbindet er sich auf die Quelladresse und die Verbindung besteht. Das hat den großen Vorteil dass die Messenger Komponente nur dann gestartet wird wenn sie wirklich benötigt wird. Eine Teilklasse des Messengers ist Receive. Diese sorgt dafür das der Messenger alle Nachrichten die er bekommt auch wirklich entgegen nimmt. while(true) { String msg = CORE.readMessage(); if(msg.equals("quit")) { CORE.sendMessage("quit",false); break; } else { GUI.write(CORE.getConIP()+": "+msg+"\n"); } } Außerdem beinhaltet der Messenger eine Methode die überprüft ob die eingegeben IP-Adresse überhaupt gültig sein kann. 7 Startup Eine besondere Herausforderung stellte der Startup Eintrag in das OS dar. Denn Java unterstützt dies leider (noch) nicht. Deswegen wurde eine eigene Klasse erstellt die dies unterstützt. Das System dabei ist relativ simpel und einfach durchdacht. Jedoch ist ein riesiger Aufwand zu betreiben da für jedes System (Windows, Mac, Linux usw.) eigene Routinen geschrieben werden mussten. Es wird zuerst überprüft um welches Betriebssystem es sich handelt, dazu wird einfach die jeweilige Java Eigenschaft ausgelesen. sOS = System.getProperty("os.name"); Dazu kommt noch, dass jetzt auch noch zwischen den einzelnen Sprachen unterschieden werden muss, da die Startup Einträge je nach Sprache unterschiedliche Ordner besitzen. Als Beispiel Windows XP deutsch - englisch: Startmenü\\Programme\\Autostart\\ zu Startmenu\\Programs\\Autostart\\ Konnte dann Betriebssystem und Sprache ausfindig gemacht warden muss noch je nach System eine Script Datei in dem Ordner erstellt werden die Superior bei Systemstart aufruft. Unter Windows: Eine .bat File mit folgendem Inhalt „@START javaw –jar PROGRAMMPFAD“ Linux Eine .sh File mit diesem Inhalt: „#!/bin/sh\njavaw –jar PROGRAMMPFAD“ Da bis jetzt noch kein Mac Rechner zur Verfügung stand werden im Moment nur Linux und Windows berücksichtigt. Außerdem nur die Sprachen Deutsch & Englisch da es viel zu aufwändig / speicherintensiv wäre mehrere Sprachen zu behandeln. Hoffentlich beinhaltet Java in den kommenden Versionen eine Klasse die diese Aufgabe übernehmen kann. Derweil wurde in unserem Projekt eine eigene, funktionstüchtige Klasse geschrieben die so abgekapselt wurde, dass sie jederzeit von anderen Programmen auch verwendet werden kann. 8 Update Auch das Update Fenster wurde mit dem gewissen Etwas ausgestattet. So wird zur Laufzeit Verbindung mit dem Server aufgenommen und überprüft ob die Version noch aktuell ist. Ist dies nicht der Fall wird der User darauf hingewiesen und bekommt einen dynamisch generierten Link der sofort zum Download der neuen Version führt. Doch wie wird das realisiert? Das erste Problem ist, überhaupt einen anklickbaren Link zu erstellen, der dem Fenster hinzugefügt werden kann. Dazu wurde extra ein eigenes Pane benutzt.Auf dieses wird jedoch später im GUI-Teil näher eingegangen. Die Verbindung besteht aus zwei Teilen: Zuerst wird mit folgendem Java Programm die aktuelle Version an den Server übertragen. URL url = new URL(WEBSITE+UPDATE+SERVER.getVersionID()); Auf der Website wird die Anfrage entgegengenommen und die übergebene VersionID mit der Aktuellen (auf der Website gespeicherten) mittels PHP überprüft. $VERSION = 1.0; $versionID = $_GET['ver']; if($versionID != "") { if($versionID == $VERSION) { Stimmen die Versionen überein wird ein OK ausgegeben, ansonsten die aktuelle Version mit dem Link dazu. Die Ausgabe wird wiederum vom Server gelesen und interpretiert. Je nach Rückgabewert wird dann der Benutzer informiert ob die Version aktuell ist oder nicht. Eine ähnliche Verbindung zwischen Server und Website besteht auch bei der Global Connection. Jedoch wird in dieser Dokumentation nicht mehr näher darauf eingegangen da diese ursprünglich nicht geplant wurde. Kurz zusammenfassend kann man jedoch sagen das über den selben URL-Aufruf die IP des Server der Website mitgeteilt wird diese trägt die IP danach in eine Datenbank ein. Dort ist sie jederzeit abrufbar und kann verwendet werden um eine Verbindung zu dem Rechner aufzubauen. Zusätzlich wird noch das Land, die Sprache, und das Betriebssystem übertragen um genauere Informationen von den Benutzern zu erhalten. Diese können dann verwendet werden um das Programm noch besser auf die jeweiligen Benutzer anzupassen. 9 GUI Graphical User Interface Die grafische Benutzerschnittstelle wurde durch die Verwendung des sogenannten „System Tray“ bzw. des „Infobereiches“ realisiert der sich typischerweise im unteren Bereich des Desktops befindet. Hier werden, im Hintergrund laufende, Programme in Form von Icons angezeigt. Mittels Java kann auf diesen Bereich zugegriffen und neue Tray Icons erzeugt werden. Das Menü wird durch Rechtsklick auf das Icon geöffnet. Die Iconfarbe des Tray Icons ändert sich je nach Status des Programmes. Online: Superior ist online und bereit Berechnungen entgegenzunehmen und auszuführen Compute: Das System führt eine Berechnung durch Error: Ein Fehler ist aufgetreten. Informationen über die Art des Fehlers meist im Terminal Offline: Superior ist offline und es können keine Berechnungen durchgeführt werden Warning: Kein schwerwiegender Fehler. Informationen über die Art der Warnung meist im Terminal 10 Das Menü Prinzipiell besteht das Menü aus Einträgen verschiedener Art. Zwei bieten Information über das Programm selbst bzw. Updateinfos. Das Terminal ermöglicht die Darstellung von aktuellen Informationen, Meldungen, Warnungen usw. Der Messenger ist ein Hilfsprogramm um zwischen den einzelnen Teilnehmern kommunizieren zu können. Es findet sich auch ein Untermenü mit Hilfe dessen verschiedenste Einstellungen via Checkboxen vorgenommen werden können. Mit „Shutdown“ kann das Programm beendet werden. Informationsfenster (About & Update) Da weder Maximieren noch Minimieren benötigt werden fällt die Wahl des Fenstertyps hier auf den JDialog. Um HTML-Code, und damit Hyperlinks sowie bestimmte Farben und Formatierungen anzeigen zu können muss dem verwendeten JDialog ein spezielles Panel hinzugefügt werden. Der unten angegebene Code, beschreibt das Erstellen der benötigten JEditorPane. String settings="<html><body style=\"background color:#FFFFFF\">"; JEditorPane pane = new JEditorPane("text/html",settings+information); pane.addHyperlinkListener(this); window.add(pane); 11 Der String, der der JEditorPane hinzugefügt wird, kann nun also HTML-Tags enthalten die anschließend durch oben angegeben Code im Fenster angezeigt werden. Mit Hilfe eines HyperlinkListener wird bei Klick auf Links direkt der Browser und die gewünschte Webseite geöffnet wie der unten angeführte Programmausschnitt zeigt. public void hyperlinkUpdate(HyperlinkEvent hle) { if(HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType())) { try { Desktop.getDesktop().browse(new URI(hle.getURL().toString())); Beide Informationsfenster, sowohl das About-, also auch das Update-Fenster beziehen bestimmte Informationen direkt vom Server und sind somit dynamisch. Updates Abhängig davon, ob eine neue Version vorhanden oder ob das Programm up to date ist wird zwischen 2 Fenstern unterschieden. Ist ein Update verfügbar werden zwei Links angezeigt. Einerseits einer zur neuen Version von Superior, andererseits ein Link zu Informationen über Änderungen bzw. eventuelle neue Funktionen. Version Die Version wird direkt vom Server bezogen und angezeigt. 12 Terminal Das Terminal zeigt verschiedenste Informationen über das Programm selbst und aktuelle Vorgänge. Prinzipiell besteht es aus 4 Teilen. 1.) Label: Dieses zeigt die IP-Adresse des Computers an, auf dem das Programm gestartet ist. (Die eigene IP) 2.) Tabelle: In der Tabelle werden Informationen über die einzelnen Komponenten von Superior gezeigt. 3.) Log: Grundsätzlich werden alle Konsolenausgaben umgeleitet und hier angezeigt. 4.) Save-, Delete- und Closebutton. Tabelle Wie im Terminal zu sehen ist, sollen in der Tabelle die Begriffe „online“ und „offline“ in bestimmten Farben dargestellt werden. Um dies zu ermöglichen, ist die Verwendung eines TableCellRenderer notwendig. table.setDefaultRenderer(Object.class,new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row, int col) { Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); //hier kann z.B. mittels c.setForeground(Color.RED); die Farbe //der Schrift geändert werden return c; } 13 GroupLayout Um die einzelnen GUI-Teile, wie im Terminal benötigt, anordnen zu können, wird ein GroupLayout benötigt. Auch hier muss angemerkt werden, dass verfügbare Tutorials oder Erklärungen im Internet mehr als komplex sind und oft nur sehr schwer verständlich sind. Mit den hier angeführten Informationen, dürfte das doch eher komplizierte GroupLayout in einer anderen Art und Weise erklärt, und so einfacher zu verstehen sein. Weitere selbst erstellte Tutorials können übrigens auf der Website gefunden werden. (www.superior.eu.ki) Bei Erstellen eines GroupLayout muss die gewünschte Anordnung von Komponenten in 2 Richtungen betrachtet werden. Einerseits Horizontal, andererseits Vertikal. Beide Dimensionen sind separat zu behandeln und anschließend dem Layout hinzuzufügen. Grundsätzlich wird jeder HorizontalGroup bzw. VerticalGroup vorerst eine SequentialGroup angefügt um überhaupt erst das weitere Hinzufügen von Elementen zu ermöglichen. Will man nun horizontal betrachtet, Elemente untereinander anordnen so wird, wie auch in der unten abgebildeten Skizze ersichtlich ist, eine ParallelGroup erforderlich. Wollen Elemente nebeneinander angeordnet werden, muss hier eine SequentialGroup verwendet werden. Umgekehrt funktioniert dies auch für die vertikale Betrachtung des Layouts. Sollen Elemente untereinander angeordnet werden, benötigt man eine SequentialGroup. Nebeneinander ist hier eine ParallelGroup erforderlich. Werden diese „Regeln“ beachtet kann prinzipiell jede Anordnung von beliebig vielen Elementen erreicht werden. Gaps Unter einem „Gap“ kann man sich ein unsichtbares Element einer gewissen Größe vorstellen. Gaps können Gruppen in ähnlicher Weise wie Elemente hinzugefügt werden. Sie dienen der gezielten Steuerung von Abständen zwischen Komponenten oder Rändern. Gaps wurden beim GUI des Messengers benötigt. Auf der nächsten Seite ist der Code für das Superior-Terminal angeführt, wodurch das Layout leichter zu verstehen sein müsste. Zusätzlich abgebildet jeweils die Betrachtung in horizontaler bzw. vertikaler Dimension. 14 HorizontalGroup layout.setHorizontalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(CENTER) .addComponent(component1) .addComponent(component2) .addComponent(component3) .addGroup(layout.createSequentialGroup() .addComponent(component4) .addComponent(component5) .addComponent(component6))) ); VerticalGroup layout.setVerticalGroup(layout.createSequentialGroup() .addComponent(component1) .addComponent(component2) .addComponent(component3) .addGroup(layout.createParallelGroup(CENTER) .addComponent(component4) .addComponent(component5) .addComponent(component6)) ); 15 Messenger Der Messenger ermöglicht die Kommunikation zweier Teilnehmer. Auch hier wurde zur Erstellung des GUI das bereits vorher beschriebene GroupLayout verwendet. Durch den, in der Menüleiste vorhandenen, Eintrag „Connect“ wird ein Fenster geöffnet in dem die IPAdresse des gewünschten Kommunikationspartners eingegeben werden kann. Ist die Eingabe korrekt ist man verbunden und die Konversation kann starten. Im Menüpunkt „File“ gibt es einerseits die Möglichkeit das Log zu speichern, welche es außerdem beim Terminal ebenfalls gibt, und andererseits die Möglichkeit die Anwendung zu beenden. 16 Client Der Client stellt die eigentliche Schnittstelle für den Programmierer dar. Deswegen wäre wohl Bibliothek ein passenderer Name als Client jedoch erfüllt diese Bibliothek alle Eigenschaften eines Clients daher der Name. Der Client Besteht aus Insgesamt 3 Klassen: Superior, ServerManager , Execute Superior ist die eigentliche Schnittstelle, alle Methoden werden vom Programmierer über sie aufgerufen. Der ServerManager verwaltet alle Server die zurzeit in einem Netzwerk vorhanden sind. Da dies mit einem erheblichen Aufwand verbunden ist wurde eine eigene Klasse erstellt. Bei einem Methodenaufruf werden zusätzliche Algorithmen angewendet um den richtigen Server zu finden dies geschieht in der Klasse Execute. Nachfolgend ein kleines Beispielprogramm das die Verwendung von Superior gut zeigt: class Main { public static void main(String []args) throws Exception { Superior s = new Superior(); s.startWebServer("Classfiles"); s.findServer(); s.waitUntilReady(); s.execute(new PIarctan(10)); s.waitUntilFinished(); System.out.println("PI = " +s.getNextResult()); //s.getResult(0); } } Zu Beginn wird ein neues Superior Objekt angelegt. Danach muss man entweder den Pfad zu einem Webserver angegeben (von wo sich die Server dann die nötigen Class Files holen) oder man verwendet, wie in diesem Beispiel, den eigens programmierten Webserver. Dieser wurde speziell für die Freigabe von Class Files optimiert und sollte auch verwendet werden. 17 Als nächstes können entweder Server per IP mit useIP(String IP) oder mit IP-Listen (useIPList(String []IP) eingetragen werden. Oder man nutzt die eingebaute Suchfunktion findServer(). Auf jeden Fall muss danach mittels waitUntilReady() darauf gewartet werden das alle Server gefunden, eingetragen, und bereit für Berechnungen sind. Ab diesem Zeitpunkt ist Superior fertig konfiguriert und voll funktionsfähig. Anstatt Methoden jetzt per normalen Befehl aufzurufen werden sie mittels execute() über Superior ausgeführt. Die Bibliothek übernimmt dann den Rest. Der große Vorteil zeigt sich spätestens jetzt. Nach drei Zeilen Initialisierung ist das System schon einsatzbereit. Jeder weitere Befehl kostet keine Zeile Code mehr. Sollen mehrere Methoden gleichzeitig ausgeführt werden muss lediglich execute() mehrmals aufgerufen werden. Möchten man dann die Ergebnisse, wartet man mit dem Befehl waitUntilFinished() bis alle Methoden vom Server berechnet wurden. Dies ist notwendig da vor der Laufzweit ja noch nicht bekannt ist welcher Task wann und wie schnell ausgeführt wird. Zum Schluss erhält man dann die Ergebnisse entweder durch direkten Zugriff getResult(int pos) wobei die Reihung gleich mit der Reihung der Methodenaufrufe ist. Oder man bekommt mittels getNextResult() nach der Reihe die Ergebnisse. Durch die Gleichzeitige Ausführung kann die Zeit folgendermaßen ermittelt werden: Angenommen M sei die Anzahl der Methoden die ausgeführt werden, S die Anzahl der Server die zur Verfügung stehen, G die Anzahl aller Berechnungen, L die Zeit die benötigt würde um G lokal zu berechnen und t die Zeit der Methode die am längsten dauert. So ergibt sich, wenn M ≤ S dann ist G = t ==> G << L Sollten mehr Methoden aufgerufen werden als Server zur Verfügung stehen gilt G = t + k dennoch ist G << L Der Faktor k errechnet sich aus der Summe aller Zeiten die die einzelnen Methoden lokal benötigen würden und gleichzeitig zur zeitintensivsten Methode t berechnet werden. Stehen keine Server zur Verfügung oder fällt die Netzwerkverbindung aus, werden alle Methoden lokal berechnet. Dies bringt dann zwar keine Zeitersparnis, garantiert aber das alle Programme die mit Superior geschrieben wurden auch ohne Server ausgeführt werden können. 18