Eine Entwicklungsumgebung im Web IFC-Seminar WS98/99 20.01.1999 Holger Otte Ziel der Arbeit Ziel: Ausführung von Java-Programmen in einem Web-Browser • Start sowohl von Kommandozeile als auch in Browser • Zugriff auf System.in und System.out • ohne Zugriff auf native Methoden • Shell Erweiterungen: • Quellcode ansehen, • editieren und abspeichern, • neu übersetzen Inhalt • Dynamisches Zuladen und Ausführen eines Java-Programms • Umlenken der Standardeingabe und -ausgabe • ClassLoader • Aufbau des Systems – Prozeßverwaltung – Virtuelles Dateisystem – Terminaltreiber • Abschlußbetrachtung • Ausblick Dynamisches Zuladen und Ausführen eines Java-Programms • Reflection-API try { Class cl = Class.forName(className); Method m = cl.getMethod ("main", new Class[] {args.getClass()}); m.invoke (null, new Object[] {args}); } catch (ClassNotFoundException e) { } catch (InvocationTargetException e) { } catch (IllegalAccessException e) { } catch (NoSuchMethodException e) { } Umlenken der Standardeingabe und -ausgabe • Methoden der System-Klasse: – setIn(InputStream in) – setOut(PrintStream out) – setErr(PrintStream err) • obwohl System.in, System.out, System.err als public final deklariert!? • Umlenken auf TextArea => Terminaltreiber • Implementierung mit Methoden der Klasse TextArea: – append(String str) – setCaretPosition(int position) – addKeyListener(KeyListener l) Nachteile/Probleme der vorgeschlagenen Lösung • Zugriff auf Standardeingabe und -ausgabe über Klasse FileDescriptor • Probleme bei parallel betriebenen Programmen: – – – – alle Applets eines Browser laufen in einer virtuellen Maschine nur ein System.in und ein System.out für alle Applets Probleme sowohl bei zwei oder mehr Terminals, als auch in einem Terminal mit Hintergrundbetrieb • Laden von Klassen mit Class.forName() unflexibel Verbesserungsvorschlag 1: Verteiler-InputStream • Idee: – System.in auf Verteiler-InputStream umlenken – Verteiler-InputStream handelt in Abhängigkeit vom lesenden Thread – entsprechender Verteiler-OutputStream Programm 1 Programm 2 Programm 3 read() System.in Verbesserungsvorschlag 1: Verteiler-InputStream • Problem: – Unterklassen von Reader synchronisieren in Methode read auf Objekt lock – lock wird in InputStreamReader auf InputStream gesetzt – mit new InputStreamReader(System.in) synchronisiert InputStream auf System.in ==> liest ein Thread, so kann kein anderer mehr lesen ==> Idee unbrauchbar Wie lädt die virtuelle Maschine dynamisch Klassen zu? • Klasse ClassLoader bzw. Unterklasse von ClassLoader • Zu Klassenname Binärform finden ==> Datei, URL, Speicher • Virtuelle Maschine: interne Tabelle mit Spalten – Klassenname – ClassLoader – Class-Objekt • Zwei Klassen sind identisch, falls: – Klassenname identisch und – ClassLoader identisch • Klasse referenziert weitere Klassen => gleicher ClassLoader Implementierung ClassLoader • Unterklasse der abstrakten Klasse java.lang.ClassLoader • Methoden: – implementieren: • Class loadClass(String name) – zurückgreifen auf: • Class defineClass(String name, byte data[], int offset, int length) • void resolveClass(Class c) • Class findSystemClass(String name) Verbesserungvorschlag 2: ClassLoader ersetzt Klasse System • ClassLoader lädt statt Systemklassen eigene Versionen dieser Klassen • eigene Klasse System: – jedes Programm bekommt seine „eigene“ Klasse System – System.in, System.out, System.err können für jedes Programm unabhängig gesetzt werden • Problem: – Java Systemklasse greift auf alte Systemklasse zu Möglichkeiten durch den Einsatz eines eigenen ClassLoaders • Klassen können flexibel zugeladen werden: – von lokaler Platte – übers Netz (URL) – aus Speicher • Programme können parallel ausgeführt werden: – jedes Programm bekommt seine „eigene“ System-Klasse • weitere System-Klassen können durch eigene ersetzt werden: – Klassen des java.io - Pakets => virtuelles Dateisystem – Runtime-Klasse • ==> Simulation Komponenten eines Betriebssystems System - Aufbau Java Programme Eigene System-Klassen virtuelles Dateisystem Prozeßverwaltung VM TerminalTreiber Prozeßverwaltung Aufgaben • Sicherheitsbeschränkungen, Thread eines Prozesses darf nicht: – auf Speicherbereich eines anderen Prozesses, d.h. auf dessen Objekte und Methoden zugreifen – Threads eines anderen Prozesses manipulieren – unbeschränkt auf System-Klassen zugreifen (Bsp: System.exit()) • Prozeß besitzt eigene Standardeingabe und -ausgabe, Dateiverbindungen • kontrollierendes Terminal • Vererbung Prozeßverwaltung Realisierung • Sicherheitsbeschränkungen ==> Sandbox-Modell • innerhalb der Sandbox ist alles erlaubt, • Zugriffe auf Umgebung enden mit SecurityException • Wesentliche Konzepte: – ClassLoader – SecurityManager Prozeßverwaltung SecurityManager • befragt, bevor Systemklasse potentiell sensible Operation ausführt • ggf. Auslösen SecurityException • Beispiel: Methode canRead() in Klasse java.io.File public boolean canRead() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); } return canRead0(); } ==> SystemSecurityManager Prozeßverwaltung SystemSecurityManager • Netzwerkzugriff • Zugriffe auf das lokale Dateisystem • Virtuelle Maschine und Umgebung • Zugriff auf Threads • Anlegen eines ClassLoaders Prozeßverwaltung Implementierung • Klasse SystemSecurityManager • Klasse Process: – ProcessClassLoader – ProcessManager – ThreadGroup für User-Threads • Klasse ProcessManager – Verwaltung Prozesse – Signale vom kontrollierenden Terminal • Klasse JIDProcess – Schnittstelle für Anwendungen Prozeßverwaltung Wann ist ein Prozeß zu Ende? • Organisation von Threads in ThreadGroups • Prioritäten • Ende der Virtuellen Maschine: alle nicht Dämon-Threads beendet • Dämon-Threads – unerheblich für Frage nach dem Ende der virtuellen Maschine – Bsp.: Garbage Collection – Methode setDaemon() • Ende eines Prozesses: alle nicht Dämon-Threads des Prozesses beendet Prozeßverwaltung Lebenszyklus eines Threads VM new Thread() Thread ThreadGroup <init> setPriority() add() start() run() exit() Threadzustände: deaktiviert remove() aktiviert zerstört Prozeßverwaltung Lösungsvorschläge Ermittlung Prozeßende • Regelmäßige Überprüfung – Nachteil: Prozeßende erst mit Verzögerung festzustellen • Eigene Thread-Klasse – Problem: Threads, die in Systemklassen gestartet werden • Einklinken in remove-Methode der ThreadGroup – Nachteil: Dämon-Threads werden erfaßt • oder ... Prozeßverwaltung Realisierung: Ermittlung Prozeßende WaitThreadGroup UserThreadGroup Join() WaitThread join() WaitThread join() WaitThread join() Thread checkAccess() System Thread Thread ProcessSecurityManager Security checkAccess()Manager Virtuelles Dateisystem • Orientierung an Klassen aus dem Paket java.io.*: – File – FileDescriptor – FileInputStream, FileOutputStream • Aufbau des virtuellen Dateisystems: – FileSystem – FD, Filp – VFile, VDirectory • VFile: – – – – Datei auf Festplatte Datei auf bel. URL Datei im Speicher der Virtuellen Maschine Terminal Abschlußbetrachtung • Realisiert: – Ausführen von Java-Programmen im Browser – Parallelbetrieb mehrerer Programme – Quellcode ansehen, verändern, speichern • Problematisch – Virtuelles Dateisystem – Compilieren von Java-Klassen ==> Java-Compiler in Java geschrieben ==> Quellen von SUN Ausblick • Lösung Compilerproblem • Ausbau virtuelles Dateisystem – Schnittstellen zu File-Servern – Benutzer-Management – verteiltes Dateisystem • verteilte Prozesse • Ausbau Entwicklungsumgebung – Debugger – Interface-Builder