Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Erweiterte Java Programmierung - dynamisches Laden Malte Gräper Fachbereich Technik Department Elektrotechnik und Informatik 21. Juni 2012 Malte Gräper Erweiterte Java Programmierung 1/23 Übersicht Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Plugin JAR-Datei ClassLoader Class-File-Format Malte Gräper Erweiterte Java Programmierung 2/23 Plugins dynamisch Laden Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Code kann von mehreren Programmen genutzt werden => kleinere Programme einzelne “Teile“ eines Programms können getauscht werden die Funktionalität kann erweitert werden spezielle Funktionen je nach Platform/Infrastruktur Malte Gräper Erweiterte Java Programmierung 3/23 Win/Linux Bibliotheken Erweiterte Java Programmierung Malte Gräper andere Programmiersprachen erlauben dies auch z.B. C/C++ dynamisches Laden bei Win sind dies DLLs Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat => integraler Bestandteil des BS Linux nutzt auch Bibliotheken bzw. libraries (dynamisch *.so, statisch *.a) DLL/libs sind jedoch nicht ausführbar => statische/dynamische Bibliotheken voneinander getrennt Java ist (etwas) anders Malte Gräper Erweiterte Java Programmierung 4/23 Klassen in Java Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat jede Klasse (im Source-Code) wird in eine separate Class-File übersetzt Class-File enthält alle wichtigen Informationen Basis-Klassen Methoden Attribute (Felder) uvm... jede Klasse ist (theoretisch) ausführbar, dynamisch oder statisch ladbar damit vereint eine Java-Klasse alle 3 Eigenschaften damit auf eine Klasse zugegriffen werden kann muss diese geladen sein egal ob statisch dynamisch daher gibt es ClassLoader- Konzept in Java Malte Gräper Erweiterte Java Programmierung 5/23 Plugins in Java Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat jedes Plugin ist eine Klasse, die dynamisch geladen werden kann daher kennt der Compiler die Klassen nicht Problem: Klassen können nicht “normal“ erzeugt werden => Methoden, Felder, etc unbekannt Ursache: der Compiler löst Namen zur Compile-Time auf (übersetzt in Index) z.B. Methoden Zugriff über Reflection-API möglich deshalb: Schnittstelle(n) definieren welche alle Plugins unterstützen somit weiß der Compiler welche Funktionen etc auf jeden Fall unterstützt werden Malte Gräper Erweiterte Java Programmierung 6/23 Beispiel I Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Malte Gräper einfaches Beispiel zum Laden von einer Klasse dafür URLClassLoader verwendet Erweiterte Java Programmierung 7/23 JAR-Datei Erweiterte Java Programmierung Malte Gräper Bibliothek-Format von Java dynamisches Laden enthält (mehrere) Class-Files, auch weitere Resourcen möglich Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Vorteil: alle Klassen u Daten zusammen mit Resource Manifest auch ausführbar effektiv ein Zip-Archiv nicht vorgeschriebenes Format => auch andere (selbst definierte) möglich Java stellt API zur Verfügung Malte Gräper Erweiterte Java Programmierung 8/23 JAR-API Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat kapselt Zip-Archiv => ZipInputStream/ZipOutputStream jede Datei/Ordner über ZipEntry repräsentiert Dateien können über getNextEntry durchlaufen werden (ähnlich Iterator) Zugriff auf Daten über Stream Wichtig: Längenangabe im ZipEntry nicht immer korrekt (-1) Malte Gräper Erweiterte Java Programmierung 9/23 Der Classloader I Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat in Java sind alle Klassen immer dynamisch geladen (selbst statische, anders als bei C/C++) Aufgabe ist dass Bereitstellen der Klassendaten (egal aus welcher Quelle) das eigentliche erzeugen der Klasse läuft über defineClass diese Funktion ist final u Teil der JVM jede Klassen wird über ClassLoader geladen und ist mit diesem verbunden ClassLoader integraler Bestandteil von Java Bootstrap-Loader bzw. dessen parent Teil der JVM für Anwender jedoch transparent Malte Gräper Erweiterte Java Programmierung 10/23 Der Classloader I Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Malte Gräper hierarchisch aufgebaut somit kapselt ClassLoader Sichtbarkeit von Klassen Grafik: http://media.developeriq.in Erweiterte Java Programmierung Erweiterte Java Programmierung 11/23 Der Classloader II Erweiterte Java Programmierung Malte Gräper 3 Phasen dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Laden => physikalische bereitstellen der Daten Linken Bytecode überprüfen => Konsistenz, schadhafter Code (Viren?), etc) Vorbereiten Auflösen der Abhängigkeiten (laden der Basis-Klassen etc) Initialisieren, statische Felder, Ctor etc Malte Gräper Erweiterte Java Programmierung 12/23 Der Classloader II Erweiterte Java Programmierung Grafik: http://www.techjava.de Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Malte Gräper Erweiterte Java Programmierung 13/23 Ein eigener ClassLoader Erweiterte Java Programmierung Malte Gräper erbt von der Basis-Klasse ClassLoader dynamisches Laden muss in Hierarchie eingebunden werden => parent-ClassLoader Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat findClass(String name) überschreiben, bereitstellen der Klassendaten wenn gesuchte Klasse unbekannt => an parent delegieren protected loadClass(String name,boolean resolve) evtl. überschreiben, finden der Klasse => Cache notwendig Klasse nicht mehrfach definieren daher Cache Malte Gräper Erweiterte Java Programmierung 14/23 Beispiel II Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Malte Gräper MyClassLoader-Klasse implementiert eigenen ClassLoader nur findClass-Funktion überschrieben nutzt Zip-API zum Einlesen von JAR-Dateien und entpackt diese in RAM Erweiterte Java Programmierung 15/23 ClassLoader Probleme/Möglichkeiten Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat eigene ClassLoader nicht ganz ungefährlich theoretisch kann z.B. String-Klasse ersetzt werden daher eigene ClassLoader nicht immer möglich (manche Web-Applets) Klassen können mehrfach geladen werden (aber nicht über selben ClassLoader) das kann gewollt sein (z.B. self-modifying-code) aber möglicherweise Versions-Probleme Wichtig: trotz gleichem Name => Klassen nicht identisch viele Andere Probleme möglich z.B. wenn Klasse mehrfach über verschiedene ClassLoader erzeugt Vergleiche wie Obj instanceof A nicht mehr korrekt Fazit: viele Möglichkeiten => aber vorsichtig Malte Gräper Erweiterte Java Programmierung 16/23 Beispiel III Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat MyClassLoader2 enthält MyClassLoader (nicht erben) wenn JAR-Datei erneut geladen wird, neuer MyClassLoader erzeugt somit kann auch veränderte Klasse erneut geladen werden Malte Gräper Erweiterte Java Programmierung 17/23 Java Class File Format Erweiterte Java Programmierung Java Standart spezifiziert Klassen Format Malte Gräper Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Malte Gräper Grafik: http://img.viralpatel.net dynamisches Laden Erweiterte Java Programmierung 18/23 Java Class File Format Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Information über Klasse z.B. Zugriffsrechte, Basis-Klasse etc alle Interfaces (von denen die Klasse erbt) die implementierten Methoden (z.B. <init> für Ctor) die Felder einer Klasse mit Name u weiteren Eigenschaften Attribute für die gesamte Klasse (z.B. SourceCode zur Unterstützung bei debugging) Malte Gräper Erweiterte Java Programmierung 19/23 Java Class File Format Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Malte Gräper Kern ist Constant Pool hier werden alle Daten wie Konstanten, String aber auch Typinformationen etc abgelegt in der restlichen Datei werden diese Einträge nur über Index referenziert Vorteil: Daten müssen nicht mehrfach gespeichert werden nach Laden der Klasse => Constant Pool im Speicher zugreifbar Erweiterte Java Programmierung 20/23 Java Class File Format Erweiterte Java Programmierung Grafik: http://img.viralpatel.net Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Malte Gräper Erweiterte Java Programmierung 21/23 Was kann man noch machen Erweiterte Java Programmierung Malte Gräper dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat vor dem Laden Interfaces, Methoden oder Attribute überprüfen/hinzufügen self-modifying-code synthetisch zur Laufzeit generierte Java-Klassen laden dafür gibt es bereits Bibliotheken BCEL, ASM selber schreiben => sehr aufwendig, komplex komplette Programmiersprache auf Java Bytecode abbilden (JRuby, Groovy) sehr viele Möglichkeiten (wenn auch nicht alle sinnvoll) Malte Gräper Erweiterte Java Programmierung 22/23 Beispiel IV Erweiterte Java Programmierung Malte Gräper MyClassLoader3 erweitert MyClassLoader dynamisches Laden Übersicht Plugin JAR-Datei ClassLoader Class-FileFormat Malte Gräper keine Möglichkeit zum Mehrfach-Laden jedoch wird das Class-File-Format eingelesen es kann z.B. vor dem Laden überprüft werden ob Interface vorhanden umbenennen von Funktionen (führt evtl. zu Fehlern) ändern der Klassen-Zugriffsrechte z.B. hinzufügen einer statischen Member-Variable wenn nicht vorhanden Erweiterte Java Programmierung 23/23