Class Transformer Byte-Code, Class-Loader und Class-Transformer Bernd Müller JUG Hannover 11.8.2016 Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 1/90 Class Transformer Referent Vorstellung Referent I I I I I I Prof. Informatik (Ostfalia, HS Braunschweig/Wolfenbüttel) Buchautor (JSF, Seam, JPA, ...) Mitglied EGs JSR 344 (JSF 2.2) und JSR 338 (JPA 2.1) Geschäftsführer PMST GmbH Aktiv in JUG Ostfalen ... Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 2/90 Class Transformer Motivation Motivation Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 3/90 Class Transformer Motivation Motivation I Die schlechte Nachricht: I I Bernd Müller, Ostfalia Für Anwendungsentwickler wenig direkt Verwendbares Framework-Entwickler kennen das schon ;-) , JUG Hannover, 11.8.2016 4/90 Class Transformer Motivation Motivation I Die schlechte Nachricht: I I I Für Anwendungsentwickler wenig direkt Verwendbares Framework-Entwickler kennen das schon ;-) Die gute Nachricht: I I I Bernd Müller, Ostfalia Als interessierter Java-Entwickler lohnt es sich, hinter die Kulissen zu schauen Man versteht einiges besser und wird damit besser Eventuell könnten Sie etwas Spaß haben (siehe Unit-Tests) , JUG Hannover, 11.8.2016 4/90 Class Transformer Agenda Agenda I I Klassen, Byte-Code Class-Loader Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 5/90 Class Transformer Agenda Agenda I I I Klassen, Byte-Code Class-Loader Instrumentierung und Class Transformer I I I Bernd Müller, Ostfalia Was ist das? Agenten, Start von Agenten Redefinition, Retransformation , JUG Hannover, 11.8.2016 5/90 Class Transformer Agenda Agenda I I I Klassen, Byte-Code Class-Loader Instrumentierung und Class Transformer I I I I Was ist das? Agenten, Start von Agenten Redefinition, Retransformation Beispiele I I I I Bernd Müller, Ostfalia Monitoring Hot Code Replacement Unit Tests ;-) ? , JUG Hannover, 11.8.2016 5/90 Class Transformer Klassen Klassen oder Wie sieht das binäre Format einer Java-Klasse aus? Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 6/90 C-Struct ClassFile ClassFile { u4 magic ; u2 minor_version ; u2 major_version ; u2 co n s ta n t _ po o l _c o u nt ; cp_info constant_pool [ constant_pool_count -1]; u2 access_flags ; u2 this_class ; u2 super_class ; u2 interfaces_count ; u2 interfaces [ interfaces_count ]; u2 fields_count ; field_info fields [ fields_count ]; u2 methods_count ; method_info methods [ methods_count ]; u2 attributes_count ; attribute_info attributes [ attributes_count ]; } Class Transformer Klassen Klassenstruktur (C-Struct) C-Struct ClassFile (cont’d) I magic: Magic Number zur Formatidentifizierung, Wert: 0xCAFEBABE Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 8/90 Class Transformer Klassen Klassenstruktur (C-Struct) C-Struct ClassFile (cont’d) I magic: Magic Number zur Formatidentifizierung, Wert: 0xCAFEBABE I minor version, major version: Versionsnummer für Class-File-Format 1.0 45.0 1.1 45.3 Bernd Müller, Ostfalia 1.2 46.0 1.3 47.0 1.4 48.0 , JUG Hannover, 11.8.2016 5.0 49.0 6.0 50.0 7.0 51.0 8.0 52.0 9.0 (EA) 52.0 ... ... 8/90 Class Transformer Klassen Klassenstruktur (C-Struct) C-Struct ClassFile (cont’d) I magic: Magic Number zur Formatidentifizierung, Wert: 0xCAFEBABE I minor version, major version: Versionsnummer für Class-File-Format 1.0 45.0 I 1.1 45.3 1.2 46.0 1.3 47.0 1.4 48.0 5.0 49.0 6.0 50.0 7.0 51.0 8.0 52.0 9.0 (EA) 52.0 ... ... constant pool count, constant pool[]: Structs, für String-Literale, Klassen-, Interface-, Field-Namen, etc., die in Klasse referenziert werden Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 8/90 Class Transformer Klassen Klassenstruktur (C-Struct) C-Struct ClassFile (cont’d) I magic: Magic Number zur Formatidentifizierung, Wert: 0xCAFEBABE I minor version, major version: Versionsnummer für Class-File-Format 1.0 45.0 1.1 45.3 1.2 46.0 1.3 47.0 1.4 48.0 5.0 49.0 6.0 50.0 7.0 51.0 8.0 52.0 9.0 (EA) 52.0 ... ... I constant pool count, constant pool[]: Structs, für String-Literale, Klassen-, Interface-, Field-Namen, etc., die in Klasse referenziert werden I ... Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 8/90 Class Transformer Klassen Klassenstruktur (C-Struct) Eine einfache (und sinnlose) Klasse als Beispiel package de . pdbm . simple ; public class Main { static final int CONST = 4711; private int i ; private String hello = " Hello World ! " ; public Main () { i = CONST ; } public static void main ( String [] args ) { Main main = new Main (); System . out . println ( main . hello + main . i ); } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 9/90 Class Transformer Klassen Klassenstruktur (C-Struct) Ausgabe von hexdump -C Main.class“ ” 00000000 00000010 00000020 00000030 00000040 00000050 00000060 00000070 00000080 00000090 000000a0 000000b0 000000c0 000000d0 000000e0 000000f0 00000100 00000110 ... Ostfalia Bernd Müller, ca 64 61 6e 54 56 05 61 6e 65 0c 00 06 62 62 00 65 16 fe 65 69 67 01 61 68 6e 69 0a 48 14 01 6c 6c 15 2f 28 ba 2f 6e 2f 00 6c 65 67 74 00 65 0c 00 65 65 4c 4d 5b be 70 07 4f 01 75 6c 2f 3e 03 6c 00 0f 01 54 64 61 4c 00 64 00 62 49 65 6c 53 01 00 6c 0a 4c 00 61 65 69 6a 00 62 04 6a 01 03 6f 74 00 10 6f 00 69 12 62 2f 6e 61 00 6d 01 65 00 00 01 72 03 0c 20 0b 6e 4c 6c 70 3b 76 , JUG Hannover, 11.8.2016 33 2f 00 63 0d 00 00 69 28 00 57 09 65 6f 65 64 01 61 00 73 10 74 43 12 12 6e 29 0c 6f 00 4e 63 01 62 00 2f 40 69 6a 01 6f 67 4c 67 56 00 72 01 75 61 00 6d 04 6c 07 6d 61 00 6e 01 6a 3b 01 0d 6c 00 6d 6c 04 2f 6d 61 00 70 76 05 73 00 61 01 00 08 64 16 62 56 74 73 61 6e 02 6c 61 43 74 01 76 00 04 00 21 0c 65 61 68 69 69 67 01 65 2f 4f 61 69 61 06 43 12 09 00 72 72 69 6d 6e 2f 00 2f 6c 4e 6e 01 2f 3c 6f 01 00 09 54 69 73 70 01 53 13 4d 61 53 74 00 6c 69 64 00 01 00 61 61 01 6c 00 74 |.......3.@......| |de/pdbm/simple/M| |ain......java/la| |ng/Object...CONS| |T...I...Constant| |Value....g...i..| |.hello...Ljava/l| |ang/String;...<i| |nit>...()V...Cod| |e...............| |.Hello World!...| |................| |....LineNumberTa| |ble...LocalVaria| |bleTable...this.| |..Lde/pdbm/simpl| |e/Main;...main..| |.([Ljava/lang/St| 10/90 Class Transformer Klassen Klassenstruktur (C-Struct) Ausgabe von hexdump -C Main.class“ ” 00000000 00000010 00000020 00000030 00000040 00000050 00000060 00000070 00000080 00000090 000000a0 000000b0 000000c0 000000d0 000000e0 000000f0 00000100 00000110 ... Ostfalia Bernd Müller, ca 64 61 6e 54 56 05 61 6e 65 0c 00 06 62 62 00 65 16 fe 65 69 67 01 61 68 6e 69 0a 48 14 01 6c 6c 15 2f 28 ba 2f 6e 2f 00 6c 65 67 74 00 65 0c 00 65 65 4c 4d 5b be 70 07 4f 01 75 6c 2f 3e 03 6c 00 0f 01 54 64 61 4c 00 64 00 62 49 65 6c 53 01 00 6c 0a 4c 00 61 65 69 6a 00 62 04 6a 01 03 6f 74 00 10 6f 00 69 12 62 2f 6e 61 00 6d 01 65 00 00 01 72 03 0c 20 0b 6e 4c 6c 70 3b 76 , JUG Hannover, 11.8.2016 33 2f 00 63 0d 00 00 69 28 00 57 09 65 6f 65 64 01 61 00 73 10 74 43 12 12 6e 29 0c 6f 00 4e 63 01 62 00 2f 40 69 6a 01 6f 67 4c 67 56 00 72 01 75 61 00 6d 04 6c 07 6d 61 00 6e 01 6a 3b 01 0d 6c 00 6d 6c 04 2f 6d 61 00 70 76 05 73 00 61 01 00 08 64 16 62 56 74 73 61 6e 02 6c 61 43 74 01 76 00 04 00 21 0c 65 61 68 69 69 67 01 65 2f 4f 61 69 61 06 43 12 09 00 72 72 69 6d 6e 2f 00 2f 6c 4e 6e 01 2f 3c 6f 01 00 09 54 69 73 70 01 53 13 4d 61 53 74 00 6c 69 64 00 01 00 61 61 01 6c 00 74 |.......3.@......| |de/pdbm/simple/M| |ain......java/la| |ng/Object...CONS| |T...I...Constant| |Value....g...i..| |.hello...Ljava/l| |ang/String;...<i| |nit>...()V...Cod| |e...............| |.Hello World!...| |................| |....LineNumberTa| |ble...LocalVaria| |bleTable...this.| |..Lde/pdbm/simpl| |e/Main;...main..| |.([Ljava/lang/St| 10/90 Class Transformer Klassen Klassenstruktur (C-Struct) javap des SDKs I javap – The Java Class File Disassembler I Description The javap command disassembles one or more class files. Its output depends on the options used. If no options are used, javap prints out the package, protected, and public fields and methods of the classes passed to it. javap prints its output to stdout. Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 11/90 Class Transformer Klassen Klassenstruktur (C-Struct) Ausgabe von: javap Main.class public class de . pdbm . simple . Main { static final int CONST ; public de . pdbm . simple . Main (); public static void main ( java . lang . String []); } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 12/90 Class Transformer Klassen Klassenstruktur (C-Struct) Ausgabe von: javap -p Main.class (private) public class de . pdbm . simple . Main { static final int CONST ; private int i ; private java . lang . String hello ; public de . pdbm . simple . Main (); public static void main ( java . lang . String []); } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 13/90 Class Transformer Klassen Klassenstruktur (C-Struct) Ausgabe von: javap -constants Main.class public class de . pdbm . simple . Main { static final int CONST = 4711; public de . pdbm . simple . Main (); public static void main ( java . lang . String []); } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 14/90 Ausgabe von: javap -v Main.class (verbose) Constant pool: #1 = Class #2 = Utf8 #3 = Class #4 = Utf8 #5 = Utf8 #6 = Utf8 #7 = Utf8 #8 = Integer #9 = Utf8 #10 = Utf8 #11 = Utf8 #12 = Utf8 #13 = Utf8 #14 = Utf8 #15 = Methodref #16 = NameAndType #17 = String #18 = Utf8 ... #2 // de/pdbm/simple/Main de/pdbm/simple/Main #4 // java/lang/Object java/lang/Object CONST I ConstantValue 4711 i hello Ljava/lang/String; <init> ()V Code #3.#16 // java/lang/Object."<init>":()V #12:#13 // "<init>":()V #18 // Hello World! Hello World! Class Transformer Klassen Klassenstruktur (C-Struct) Der Constant Pool cp_info { u1 tag ; u1 info []; } I Also: Ein Byte für Tag, ein Byte für Info I Tag beschreibt Struktur für Info Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 16/90 Class Transformer Klassen Klassenstruktur (C-Struct) Constant Pool Beispiel #1 #2 #3 #4 I I I I 1: 2: 3: 4: = = = = Class Utf8 Class Utf8 #2 // de/pdbm/simple/Main de/pdbm/simple/Main #4 // java/lang/Object java/lang/Object Klasse referenziert Utf8 (ein String) Utf8 referenziert de/pdbm/simple/Main Klasse referenziert Utf8 Utf8 referenziert java/lang/Object, die Oberklasse Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 17/90 Class Transformer Klassen Klassenstruktur (C-Struct) Constant Pool Beispiel (cont) #5 #6 #7 #8 I I I I 5: 6: 7: 8: = = = = Utf8 Utf8 Utf8 Integer CONST I ConstantValue 4711 Variable (Name) vom Typ Integer mit Wert 4711 Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 18/90 Class Transformer Klassen Klassenstruktur (C-Struct) Constant Pool I Dieses Format des Constant Pools wird beim Laden einer Klasse in die VM verifiziert, d.h. auf Konsistenz geprüft I Für uns ist es bis hier her ok. Wir wollen das nicht im Detail verstehen I Sondern uns den interessanteren Dingen zuwenden I Bemerkung: Das vorgestellte Format ist VM-spezifisch, nicht Java-spezifisch. Andere VM-Sprachen (Groovy, Scala, . . . ) müssen sich ebenfalls daran halten Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 19/90 Class Transformer Klassen Klassenstruktur (C-Struct) Werkzeugunterstützung I Das Werkzeug jclasslib ist ein Byte-Code-Viewer I Von der Firma EJ-Technologies I Open-Source unter GPL I Verfügbar: http://www.ej-technologies.com/products/jclasslib/overview.html I Zusätzlich Bibliothek für den Zugriff auf den Byte-Code Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 20/90 Class Transformer Class-Loader Class-Loader oder Wie kommen die Klassen in die VM? Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 21/90 Class Transformer Class-Loader Motivation: Ein Blick hinter die Kulissen I Class-Loader arbeiten im Hintergrund, daher für Hello-World-Niveau vernachlässigbar Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 22/90 Class Transformer Class-Loader Motivation: Ein Blick hinter die Kulissen I Class-Loader arbeiten im Hintergrund, daher für Hello-World-Niveau vernachlässigbar I Für Java 1.1 gezeigt, dass der FQN nicht reicht: Java is not type-safe, Vijay Saraswat, AT&T Research, 1997 Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 22/90 Class Transformer Class-Loader Motivation: Ein Blick hinter die Kulissen I Class-Loader arbeiten im Hintergrund, daher für Hello-World-Niveau vernachlässigbar I Für Java 1.1 gezeigt, dass der FQN nicht reicht: Java is not type-safe, Vijay Saraswat, AT&T Research, 1997 I In Java 1.2 neue Class-Loader-Architektur, die seither Bestand hat Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 22/90 Class Transformer Class-Loader Motivation: Ein Blick hinter die Kulissen I Class-Loader arbeiten im Hintergrund, daher für Hello-World-Niveau vernachlässigbar I Für Java 1.1 gezeigt, dass der FQN nicht reicht: Java is not type-safe, Vijay Saraswat, AT&T Research, 1997 I In Java 1.2 neue Class-Loader-Architektur, die seither Bestand hat I Einige SDK-Klassen haben einen Parameter vom Typ ClassLoader und es gibt Implementierungen der Klasse ClassLoader Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 22/90 Class Transformer Class-Loader Motivation: Ein Blick hinter die Kulissen I Class-Loader arbeiten im Hintergrund, daher für Hello-World-Niveau vernachlässigbar I Für Java 1.1 gezeigt, dass der FQN nicht reicht: Java is not type-safe, Vijay Saraswat, AT&T Research, 1997 I In Java 1.2 neue Class-Loader-Architektur, die seither Bestand hat I Einige SDK-Klassen haben einen Parameter vom Typ ClassLoader und es gibt Implementierungen der Klasse ClassLoader I Class-Loader wichtig in Java-EE. Was sagt die Spezifikation? Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 22/90 Class Transformer Class-Loader Java EE 6 (JSR 316) I EE.8.3 Class Loading Requirements The Java EE specification purposely does not define the exact types and arrangements of class loaders that must be used by a Java EE product. Instead, the specification defines requirements in terms of what classes must or must not be visible to components. A Java EE product is free to use whatever class loaders it chooses to meet these requirements. Portable applications must not depend on the types of class loaders used or the hierarchical arrangement of class loaders, if any. Applications should use the techniques described in Section EE.8.2.5, “Dynamic Class Loading” if they need to load classes dynamically. Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 23/90 Class Transformer Class-Loader Class-Loader Basics I Die VM I I I lädt linkt und initialisiert Klassen und Interfaces dynamisch Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 24/90 Class Transformer Class-Loader Class-Loader Basics I Die VM I I I I lädt linkt und initialisiert Klassen und Interfaces dynamisch Laden: Finden einer Binärdarstellung eines Klassen- oder Interface-Typs eines bestimmten Namen und Erzeugen der Klasse/Interface aus dieser Binärdarstellung Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 24/90 Class Transformer Class-Loader Class-Loader Basics I Die VM I I I I I lädt linkt und initialisiert Klassen und Interfaces dynamisch Laden: Finden einer Binärdarstellung eines Klassen- oder Interface-Typs eines bestimmten Namen und Erzeugen der Klasse/Interface aus dieser Binärdarstellung Linking: Einfügen der Klasse/Interface in den aktuellen Laufzeitzustand der VM, so dass sie verwendet werden kann Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 24/90 Class Transformer Class-Loader Class-Loader Basics I Die VM I I I I I I lädt linkt und initialisiert Klassen und Interfaces dynamisch Laden: Finden einer Binärdarstellung eines Klassen- oder Interface-Typs eines bestimmten Namen und Erzeugen der Klasse/Interface aus dieser Binärdarstellung Linking: Einfügen der Klasse/Interface in den aktuellen Laufzeitzustand der VM, so dass sie verwendet werden kann Initialisierung: Ausführen der Initialisierungsmethode <clinit> Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 24/90 Class Transformer Class-Loader Laden und Linken I Laden erzeugt (mit ein paar grundlegenden Prüfungen) ein Class-Objekt, das aber noch nicht verwendet werden kann Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 25/90 Class Transformer Class-Loader Laden und Linken I I Laden erzeugt (mit ein paar grundlegenden Prüfungen) ein Class-Objekt, das aber noch nicht verwendet werden kann Linken besteht aus weiteren einzelnen Schritten: I I I Bernd Müller, Ostfalia Verification Preparation Resolution , JUG Hannover, 11.8.2016 25/90 Class Transformer Class-Loader Verification I Die Verifikation bestätigt, dass sich die Klasse gutmütig“ verhält und keine ” Laufzeitprobleme verursacht Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 26/90 Class Transformer Class-Loader Verification I I Die Verifikation bestätigt, dass sich die Klasse gutmütig“ verhält und keine ” Laufzeitprobleme verursacht Einige dieser Prüfungen: I I I I I I I I I Bernd Müller, Ostfalia Constant Pool konsistent Keine final-Methoden überschrieben Methoden respektieren Access-Control Methoden werden mit korrekter Anzahl und Typ von Parametern aufgerufen Byte-Code manipuliert Stack nicht Variablen sind vor Verwendung initialisiert Variablen werden nur Werte passender Typen zugewiesen Aufruf des Oberklassenkonstruktors ist erste Anweisung im Konstruktor ... , JUG Hannover, 11.8.2016 26/90 Class Transformer Class-Loader Verification I I Die Verifikation bestätigt, dass sich die Klasse gutmütig“ verhält und keine ” Laufzeitprobleme verursacht Einige dieser Prüfungen: I I I I I I I I I I Constant Pool konsistent Keine final-Methoden überschrieben Methoden respektieren Access-Control Methoden werden mit korrekter Anzahl und Typ von Parametern aufgerufen Byte-Code manipuliert Stack nicht Variablen sind vor Verwendung initialisiert Variablen werden nur Werte passender Typen zugewiesen Aufruf des Oberklassenkonstruktors ist erste Anweisung im Konstruktor ... Bei Verletzung wird VerifyError geworfen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 26/90 Verfication: Kurz nach Java 8 Release bekannt geworden Class Transformer Class-Loader Preparation und Resolution I Preparation: Vorbereitung, dass Speicher für Klasse alloziert und Klassenvariablen initialisiert werden können. Initalisierung wird aber nicht durchgeführt und es wird kein Byte-Code ausgeführt Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 28/90 Class Transformer Class-Loader Preparation und Resolution I I Preparation: Vorbereitung, dass Speicher für Klasse alloziert und Klassenvariablen initialisiert werden können. Initalisierung wird aber nicht durchgeführt und es wird kein Byte-Code ausgeführt Resolution: Prüft, dass alle von der Klasse referenzierten Klassen geladen sind. Falls nicht, werden diese geladen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 28/90 Class Transformer Class-Loader Preparation und Resolution I I I Preparation: Vorbereitung, dass Speicher für Klasse alloziert und Klassenvariablen initialisiert werden können. Initalisierung wird aber nicht durchgeführt und es wird kein Byte-Code ausgeführt Resolution: Prüft, dass alle von der Klasse referenzierten Klassen geladen sind. Falls nicht, werden diese geladen Wenn alle Klassen geladen sind, wird Initialisierung (Klassenvariablen und Static-Initializer-Blöcke) durchgeführt Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 28/90 Class Transformer Class-Loader Preparation und Resolution I I I I Preparation: Vorbereitung, dass Speicher für Klasse alloziert und Klassenvariablen initialisiert werden können. Initalisierung wird aber nicht durchgeführt und es wird kein Byte-Code ausgeführt Resolution: Prüft, dass alle von der Klasse referenzierten Klassen geladen sind. Falls nicht, werden diese geladen Wenn alle Klassen geladen sind, wird Initialisierung (Klassenvariablen und Static-Initializer-Blöcke) durchgeführt Wenn das abgeschlossen ist, steht die Klasse zur Verwendung bereit Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 28/90 Class Transformer Class-Loader API-Doc ClassLoader public abstract class ClassLoader extends Object A class loader is an object that is responsible for loading classes. The class ClassLoader is an abstract class. . . . Every Class object contains a reference to the ClassLoader that defined it. . . . Applications implement subclasses of ClassLoader in order to extend the manner in which the Java virtual machine dynamically loads classes. Class loaders may typically be used by security managers to indicate security domains. Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 29/90 API-Doc ClassLoader (cont’d) The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine’s built-in class loader, called the ”bootstrap class loader”, does not itself have a parent but may serve as the parent of a ClassLoader instance. Class loaders that support concurrent loading of classes are known as parallel capable class loaders and are required to register themselves at their class initialization time by invoking the ClassLoader.registerAsParallelCapable method. Note that the ClassLoader class is registered as parallel capable by default. However, its subclasses still need to register themselves if they are parallel capable. In environments in which the delegation model is not strictly hierarchical, class loaders need to be parallel capable, . . . Class Transformer Class-Loader Class-Loader-Basics zum Zweiten I Henne-Ei-Problem: Erzeugung einer Class-Loader-Instanz setzt voraus, dass dieser Class-Loader bereits geladen wurde. Von wem? Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 31/90 Class Transformer Class-Loader Class-Loader-Basics zum Zweiten I Henne-Ei-Problem: Erzeugung einer Class-Loader-Instanz setzt voraus, dass dieser Class-Loader bereits geladen wurde. Von wem? I Der Class-Loader ist eine normale Klasse und leitet von Object ab. Object muss also geladen worden sein. Von wem? Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 31/90 Class Transformer Class-Loader Class-Loader-Basics zum Zweiten I Henne-Ei-Problem: Erzeugung einer Class-Loader-Instanz setzt voraus, dass dieser Class-Loader bereits geladen wurde. Von wem? I Der Class-Loader ist eine normale Klasse und leitet von Object ab. Object muss also geladen worden sein. Von wem? I Im API-Doc schon genannt: der Bootstrap-Class-Loader auch Primordinal Class-Loader genannt Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 31/90 Class Transformer Class-Loader Class-Loader-Basics zum Zweiten I Henne-Ei-Problem: Erzeugung einer Class-Loader-Instanz setzt voraus, dass dieser Class-Loader bereits geladen wurde. Von wem? I Der Class-Loader ist eine normale Klasse und leitet von Object ab. Object muss also geladen worden sein. Von wem? I Im API-Doc schon genannt: der Bootstrap-Class-Loader auch Primordinal Class-Loader genannt I Und durch das Delegationsmodell ergibt sich eine Hierarchie: Alle Class-Loader haben einen Parent außer Bootstrap-Class-Loader Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 31/90 Class Transformer Class-Loader Class-Loader-Hierarchie I Bootstrap-Class-Loader I I I I I I Bernd Müller, Ostfalia Sehr früh bei VM-Start instanziiert Meist nativ implementiert Gehört praktisch zur VM Lädt System-JARs, z.B. rt.jar Verifiziert nicht Path-Property: sun.boot.class.path , JUG Hannover, 11.8.2016 32/90 Class Transformer Class-Loader Class-Loader-Hierarchie I Bootstrap-Class-Loader I I I I I I I Sehr früh bei VM-Start instanziiert Meist nativ implementiert Gehört praktisch zur VM Lädt System-JARs, z.B. rt.jar Verifiziert nicht Path-Property: sun.boot.class.path Extension-Class-Loader I I I Bernd Müller, Ostfalia Lädt Standarderweiterungen Path-Property: java.ext.dirs Klasse: sun.misc.Launcher$ExtClassLoader , JUG Hannover, 11.8.2016 32/90 Class Transformer Class-Loader Class-Loader-Hierarchie (cont’d) I Application-Class-Loader I I I I Bernd Müller, Ostfalia Lädt Anwendungsklassen In SE der Class-Loader, der die meisten Klassen lädt Path-Property: java.class.path Klasse: sun.misc.Launcher$AppClassLoader , JUG Hannover, 11.8.2016 33/90 Class Transformer Class-Loader Class-Loader-Hierarchie (cont’d) I Application-Class-Loader I I I I I Lädt Anwendungsklassen In SE der Class-Loader, der die meisten Klassen lädt Path-Property: java.class.path Klasse: sun.misc.Launcher$AppClassLoader Custom-Class-Loader I I I Bernd Müller, Ostfalia Wird in Java-EE benötigt, um Spec zu erfüllen Jeder (Sie?) kann eigenen Class-Loader schreiben Bekanntes Beispiel: JBoss Modules , JUG Hannover, 11.8.2016 33/90 Class Transformer Class-Loader Class-Loader-Hierarchie (cont’d) I Application-Class-Loader I I I I I Lädt Anwendungsklassen In SE der Class-Loader, der die meisten Klassen lädt Path-Property: java.class.path Klasse: sun.misc.Launcher$AppClassLoader Custom-Class-Loader I I I Bernd Müller, Ostfalia Wird in Java-EE benötigt, um Spec zu erfüllen Jeder (Sie?) kann eigenen Class-Loader schreiben Bekanntes Beispiel: JBoss Modules , JUG Hannover, 11.8.2016 Bootstrap Extension Application Plattform Custom Custom: EE Custom: XY 33/90 Kann man das überprüfen? I 1: 2: 3: 12: 55: 223: 228: 243: 244: 245: 247: 256: 259: 317: 318: 319: 321: 383: 384: 385: Class-Loader-Option der VM: -verbose:class [Opened /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded java.lang.Object from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded java.io.Serializable from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded java.lang.ClassLoader from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded sun.reflect.DelegatingClassLoader from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded java.lang.ClassLoader$3 from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded java.lang.ClassLoader$NativeLibrary from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded java.security.SecureClassLoader from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded java.net.URLClassLoader from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded sun.misc.Launcher$ExtClassLoader from /usr/lib/jvm/.../jre/lib/rt.jar] [Loaded java.lang.ClassLoader$ParallelLoaders from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.4. [Loaded java.net.URLClassLoader$7 from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.4.3.0.fc19.x86 [Loaded sun.misc.Launcher$ExtClassLoader$1 from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.4.3.0 [Loaded sun.misc.Launcher$AppClassLoader from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.4.3.0.f [Loaded sun.misc.Launcher$AppClassLoader$1 from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.4.3.0 [Loaded java.lang.SystemClassLoaderAction from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.4.3.0. [Loaded java.net.URLClassLoader$1 from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.4.3.0.fc19.x86 [Loaded de.pdbm.simple.Main from file:/home/bernd/lehre/skripte/classloader/workspace/class-load [Loaded java.lang.Void from /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.60-2.4.3.0.fc19.x86_64/jre/lib Hello World!4711 Class Transformer Class-Loader Class-Loader-Delegation I ClassLoader ist Oberklasse aller Class-Loader Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 35/90 Class Transformer Class-Loader Class-Loader-Delegation I I ClassLoader ist Oberklasse aller Class-Loader ClassLoader enthält: private final ClassLoader parent; Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 35/90 Class Transformer Class-Loader Class-Loader-Delegation I I I ClassLoader ist Oberklasse aller Class-Loader ClassLoader enthält: private final ClassLoader parent; Ganz nett: Kommentar aus src.zip: // The parent class loader for delegation // Note: VM hardcoded the offset of this field, thus all // new fields must be added *after* it. Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 35/90 Class Transformer Class-Loader Class-Loader-Delegation I I I ClassLoader ist Oberklasse aller Class-Loader ClassLoader enthält: private final ClassLoader parent; Ganz nett: Kommentar aus src.zip: // The parent class loader for delegation // Note: VM hardcoded the offset of this field, thus all // new fields must be added *after* it. I Und Konstruktor für Delegation an Parent: protected ClassLoader(ClassLoader parent) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 35/90 Class Transformer Class-Loader Class-Loader-Delegation I I I ClassLoader ist Oberklasse aller Class-Loader ClassLoader enthält: private final ClassLoader parent; Ganz nett: Kommentar aus src.zip: // The parent class loader for delegation // Note: VM hardcoded the offset of this field, thus all // new fields must be added *after* it. I I Und Konstruktor für Delegation an Parent: protected ClassLoader(ClassLoader parent) Und Methode protected Class<?> loadClass(String name, boolean resolve) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 35/90 Class Transformer Class-Loader Class-Loader-Delegation I I I ClassLoader ist Oberklasse aller Class-Loader ClassLoader enthält: private final ClassLoader parent; Ganz nett: Kommentar aus src.zip: // The parent class loader for delegation // Note: VM hardcoded the offset of this field, thus all // new fields must be added *after* it. I Und Konstruktor für Delegation an Parent: protected ClassLoader(ClassLoader parent) Und Methode protected Class<?> loadClass(String name, boolean resolve) I Falls parent null Bootstrap-Class-Loader I Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 35/90 Class Transformer Class-Loader API-Doc der Methode loadClass() Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order: 1. Invoke findLoadedClass(String) to check if the class has already been loaded. 2. Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead. 3. Invoke the findClass(String) method to find the class. If the class was found using the above steps, and the resolve flag is true, this method will then invoke the resolveClass(Class) method on the resulting Class object. Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 36/90 Class Transformer Class-Loader API-Doc der Methode loadClass() Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order: 1. Invoke findLoadedClass(String) to check if the class has already been loaded. 2. Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead. 3. Invoke the findClass(String) method to find the class. If the class was found using the above steps, and the resolve flag is true, this method will then invoke the resolveClass(Class) method on the resulting Class object. I Nennt man Parent-First-Strategie Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 36/90 Class Transformer Class-Loader Delegation an AppClassLoader public class Different { main (){ URL url = new URL ( " file ://. " ); URLClassLoader loader1 = new URLClassLoader ( new URL []{ url }); URLClassLoader loader2 = new URLClassLoader ( new URL []{ url }); System . out . println ( loader1 . equals ( loader2 )); // false System . out . println ( loader1 . getParent ()); // AppClassLoader System . out . println ( loader2 . getParent ()); // AppClassLoader Class <? > class1 = loader1 . loadClass ( CLASS ); System . out . println ( Different . class . equals ( class1 )); // false Class <? > class2 = loader2 . loadClass ( CLASS ); System . out . println ( class2 . equals ( class1 )); // true System . out . println ( class1 . getClassLoader ()); // AppClassLoader System . out . println ( class2 . getClassLoader ()); // AppClassLoader Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 37/90 Class Transformer Class-Loader Keine Delegation public class Different { main (){ URL url = new URL ( " file ://. " ); URLClassLoader loader1 = new URLClassLoader ( new URLClassLoader loader2 = new URLClassLoader ( new System . out . println ( loader1 . equals ( loader2 )); // System . out . println ( loader1 . getParent ()); // System . out . println ( loader2 . getParent ()); // Class <? > class1 = loader1 . loadClass ( CLASS ); // ... Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 URL []{ url } , null ); URL []{ url } , null ); false null null CNFE 38/90 Class Transformer Class-Loader Beispiel Hierarchie public class Hierarchy { public static void main ( String [] args ) { ClassLoader classLoader = Hierarchy . class . getClassLoader (); do System . out . println ( classLoader ); while (( classLoader = classLoader . getParent ()) != null ); System . out . println ( Object . class . getClassLoader ()); } } I Ausgabe: sun . misc . L a u n c h e r $ A p p C l a s s L o a d e r @ 2 e d 4 a 1 d 3 sun . misc . L a u n c h e r $ E x t C l a s s L o a d e r @ 9 c c 3 b a a null Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 39/90 Class Transformer Class-Loader Thread-Context-Class-Loader I Parent-First-Strategie nicht immer möglich Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 40/90 Class Transformer Class-Loader Thread-Context-Class-Loader I Parent-First-Strategie nicht immer möglich I Beispiel: JAXP-Fabriken werden vom Bootstrap-Class-Loader geladen, da in rt.jar. Alternative Implementierungen werden aber von App-Class-Loader geladen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 40/90 Class Transformer Class-Loader Thread-Context-Class-Loader I Parent-First-Strategie nicht immer möglich I Beispiel: JAXP-Fabriken werden vom Bootstrap-Class-Loader geladen, da in rt.jar. Alternative Implementierungen werden aber von App-Class-Loader geladen I Damit muss das Laden von einem Parent- an einen Child-Loader delegiert werden, was nicht geht Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 40/90 Class Transformer Class-Loader Thread-Context-Class-Loader I Parent-First-Strategie nicht immer möglich I Beispiel: JAXP-Fabriken werden vom Bootstrap-Class-Loader geladen, da in rt.jar. Alternative Implementierungen werden aber von App-Class-Loader geladen I Damit muss das Laden von einem Parent- an einen Child-Loader delegiert werden, was nicht geht I Lösung: jedem Thread wird ein Class-Loader zugeordnet (seit Java 1.2), der nicht parent-first ist, der sogenannte Thread-Context-Class-Loader Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 40/90 Class Transformer Class-Loader Thread-Context-Class-Loader I Parent-First-Strategie nicht immer möglich I Beispiel: JAXP-Fabriken werden vom Bootstrap-Class-Loader geladen, da in rt.jar. Alternative Implementierungen werden aber von App-Class-Loader geladen I Damit muss das Laden von einem Parent- an einen Child-Loader delegiert werden, was nicht geht I Lösung: jedem Thread wird ein Class-Loader zugeordnet (seit Java 1.2), der nicht parent-first ist, der sogenannte Thread-Context-Class-Loader Abkürzung Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 40/90 Beispiel 1: Thread-Context-Class-Loader public class TCCL { public static void main ( String [] args ) { ClassLoader tccl = Thread . currentThread () . getC onte xtCla ssLo ader (); ClassLoader cl = TCCL . class . getClassLoader (); ClassLoader scl = ClassLoader . getSystemClassLoader (); System . out . println ( " TCCL : " + tccl ); System . out . println ( " CL : " + cl ); System . out . println ( " SCL : " + scl ); } } I Ausgabe: TCCL : sun . misc . L a u n c h e r $ A p p C l a s s L o a d e r @ 9 c c 3 b a a CL : sun . misc . L a u n c h e r $ A p p C l a s s L o a d e r @ 9 c c 3 b a a SCL : sun . misc . L a u n c h e r $ A p p C l a s s L o a d e r @ 9 c c 3 b a a Class Transformer Class-Loader Beispiel 2: Thread-Context-Class-Loader public class TCCL { public static void main ( String [] args ) { SAXParserFactory saxParserFactory = SAXParserFactory . newInstance (); System . out . println ( saxParserFactory . getClass ()); System . out . println ( saxParserFactory . getClass () . getClassLoader ()); } } I Ausgabe: class com . sun . org . apache . xerces . internal . jaxp . SAXParserFactoryImpl null Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 42/90 Class Transformer Class-Loader Beispiel 3: Thread-Context-Class-Loader I Gleiches Programm, aber Aufruf mit separatem Xerces java - cp / java / libs / xercesImpl . jar :. - Djavax . xml . perser . SAXParserFactory =\ org . apache . xerces . jaxp . SaxParserFactoryImpl de . pdbm . classloader . TCCL I Ausgabe: class org . apache . xerces . jaxp . SAXParserFactoryImpl sun . misc . L a u n c h e r $ A p p C l a s s L o a d e r @ 6 4 5 a d 7 b 2 Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 43/90 TCCL intern aber wieder Parent-First I I TCCL nutzt intern Parent-First-Strategie, erlaubt aber das Setzen des Class-Loaders Klasse Thread mit Methoden I I getContextClassLoader() setContextClassLoader(ClassLoader) The Java 2 platform also introduced the notion of context class loader. A thread’s context class loader is, by default, set to the context class loader of the thread’s parent. The hierarchy of threads is rooted at the primordial thread (the one that runs the program). The context class loader of the primordial thread is set to the class loader that loaded the application. So unless you explicitly change the thread’s context class loader, its context class loader will be the application’s class loader. That is, the context class loader can load the classes that the application can load. This loader is used by the Java runtime such as the RMI (Java Remote Method Invocation) to load classes and resources on behalf of the user application. The context class loader, like any Java 2 platform class loader, has a parent class loader and supports the same delegation model for class loading described previously. (SE Tutorial, Class Loading) Kleines Quiz I Was passiert, wenn zur Laufzeit Missing.class fehlt? public class Strange1 { public static void main ( String [] args ) { try { Missing m = new Missing (); } catch ( java . lang . NoClassDefFoundError e ) { ... } } } public class Strange2 { public static void main ( String [] args ) { Missing m ; try { m = new Missing (); } catch ( java . lang . NoClassDefFoundError e ) { ... } } } Class Transformer Class-Loader Randnotiz: Implementierungsabhängigkeiten Java Strange1 Strange2 Bernd Müller, Ostfalia 1.4.2 nicht abg. abgef. , JUG Hannover, 11.8.2016 5 nicht abg. abgef. 6 abgef. abgef. 7 abgef. abgef. 8 abgef. abgef. 46/90 Class Transformer Class-Loader Randnotiz: Implementierungsabhängigkeiten Java Strange1 Strange2 I I I I 1.4.2 nicht abg. abgef. 5 nicht abg. abgef. 6 abgef. abgef. 7 abgef. abgef. 8 abgef. abgef. JLS 12.2.1 The Loading Process If an error occurs during class loading, then an instance of one of the following ” subclasses of class LinkageError will be thrown at any point in the program that (directly or indirectly) uses the type.“ NoClassDefFoundError ist eine dieser Unterklassen. Es gibt also keine konkrete Aussage. Das Entstehen der Exception ist implementierungsabhängig Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 46/90 Class Transformer Instrumentierung Instrumentierung Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 47/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Was ist Instrumentierung ? Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 48/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Das Package java.lang.instrument I Java-Doc Package java.lang.instrument: Provides services that allow Java programming language agents to instrument ” programs running on the JVM. The mechanism for instrumentation is modification of the byte-codes of methods.“ Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 49/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Das Package java.lang.instrument I Java-Doc Package java.lang.instrument: Provides services that allow Java programming language agents to instrument ” programs running on the JVM. The mechanism for instrumentation is modification of the byte-codes of methods.“ I Wikipedia Instrumentation (computer programming): . . . instrumentation refers to an ability to monitor or measure the level of a ” product’s performance, to diagnose errors and to write trace information. . . .“ Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 49/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Das Package java.lang.instrument I Java-Doc Package java.lang.instrument: Provides services that allow Java programming language agents to instrument ” programs running on the JVM. The mechanism for instrumentation is modification of the byte-codes of methods.“ I Wikipedia Instrumentation (computer programming): . . . instrumentation refers to an ability to monitor or measure the level of a ” product’s performance, to diagnose errors and to write trace information. . . .“ I Lässt sich aber für beliebiges nutzen (JPA-Provider, Code-Coverage, . . . ) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 49/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Das Package java.lang.instrument (cont’d) An agent is deployed as a JAR file. An attribute in the JAR file manifest specifies the ” agent class which will be loaded to start the agent. For implementations that support a command-line interface, an agent is started by specifying an option on the command-line. Implementations may also support a mechanism to start agents some time after the VM has started. For example, an implementation may provide a mechanism that allows a tool to attach to a running application, and initiate the loading of the tool’s agent into the running application. The details as to how the load is initiated, is implementation dependent.“ Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 50/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Wie geht’s ? I Zentral: der Agent Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 51/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Wie geht’s ? I Zentral: der Agent I Deployed als Jar-File Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 51/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Wie geht’s ? I Zentral: der Agent I Deployed als Jar-File I Attribut im Manifest definiert die Agent-Klasse Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 51/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Wie geht’s ? I Zentral: der Agent I Deployed als Jar-File I Attribut im Manifest definiert die Agent-Klasse Alternativen, um Agent zu starten I Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 51/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Wie geht’s ? I Zentral: der Agent I Deployed als Jar-File I Attribut im Manifest definiert die Agent-Klasse Alternativen, um Agent zu starten I I Bernd Müller, Ostfalia Auf Kommandozeile bei VM-Start (zwingend erforderlich für Kommandozeilenimplementierungen) , JUG Hannover, 11.8.2016 51/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Wie geht’s ? I Zentral: der Agent I Deployed als Jar-File I Attribut im Manifest definiert die Agent-Klasse Alternativen, um Agent zu starten I I I Bernd Müller, Ostfalia Auf Kommandozeile bei VM-Start (zwingend erforderlich für Kommandozeilenimplementierungen) Nach VM-Start, z.B. durch nicht näher spezifiziertes Binden (optional und implementation dependent) , JUG Hannover, 11.8.2016 51/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Was kann man damit machen? I Allgemein: Instrumentieren, z.B. um zu Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 52/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Was kann man damit machen? I Allgemein: Instrumentieren, z.B. um zu I Monitoren (Visual VM, . . . ) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 52/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Was kann man damit machen? I Allgemein: Instrumentieren, z.B. um zu I Monitoren (Visual VM, . . . ) I Proxies bauen (JPA: Assoziationen, Automatic Dirty Checking,. . . ) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 52/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Was kann man damit machen? I Allgemein: Instrumentieren, z.B. um zu I Monitoren (Visual VM, . . . ) I Proxies bauen (JPA: Assoziationen, Automatic Dirty Checking,. . . ) I Code-Coverage-Werkzeuge bauen (EMMA, JaCoCo, Clover, . . . ) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 52/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Was kann man damit machen? I Allgemein: Instrumentieren, z.B. um zu I Monitoren (Visual VM, . . . ) I Proxies bauen (JPA: Assoziationen, Automatic Dirty Checking,. . . ) I Code-Coverage-Werkzeuge bauen (EMMA, JaCoCo, Clover, . . . ) I Aspektorientierte Programmierung Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 52/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Was kann man damit machen? I Allgemein: Instrumentieren, z.B. um zu I Monitoren (Visual VM, . . . ) I Proxies bauen (JPA: Assoziationen, Automatic Dirty Checking,. . . ) I Code-Coverage-Werkzeuge bauen (EMMA, JaCoCo, Clover, . . . ) I Aspektorientierte Programmierung I ... Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 52/90 Class Transformer Instrumentierung Was ist Instrumentierung ? Was kann man damit machen? I Allgemein: Instrumentieren, z.B. um zu I Monitoren (Visual VM, . . . ) I Proxies bauen (JPA: Assoziationen, Automatic Dirty Checking,. . . ) I Code-Coverage-Werkzeuge bauen (EMMA, JaCoCo, Clover, . . . ) I Aspektorientierte Programmierung I ... I Allgemein: Sinnvolles Verhalten, das nicht im Code steht, (nachträglich und nur bei Bedarf) einbauen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 52/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Komandozeile — Pre-Main Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 53/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I Syntax: -javaagent:jarpath[=options] Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 54/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I I Syntax: -javaagent:jarpath[=options] Option mehrfach verwendbar, damit mehrere Agenten Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 54/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I I I Syntax: -javaagent:jarpath[=options] Option mehrfach verwendbar, damit mehrere Agenten Manifest des Agenten-Jars muss Attribut Premain-Class enthalten Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 54/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I I I I Syntax: -javaagent:jarpath[=options] Option mehrfach verwendbar, damit mehrere Agenten Manifest des Agenten-Jars muss Attribut Premain-Class enthalten Diese Agentenklasse muss premain()-Methode enthalten Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 54/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I I I I I Syntax: -javaagent:jarpath[=options] Option mehrfach verwendbar, damit mehrere Agenten Manifest des Agenten-Jars muss Attribut Premain-Class enthalten Diese Agentenklasse muss premain()-Methode enthalten Nachdem VM initialisiert ist, werden alle premain()-Methoden in der Reihenfolge der Optionen aufgerufen, dann die main()-Methode Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 54/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I I I I I I Syntax: -javaagent:jarpath[=options] Option mehrfach verwendbar, damit mehrere Agenten Manifest des Agenten-Jars muss Attribut Premain-Class enthalten Diese Agentenklasse muss premain()-Methode enthalten Nachdem VM initialisiert ist, werden alle premain()-Methoden in der Reihenfolge der Optionen aufgerufen, dann die main()-Methode Zwei mögliche Signaturen: public static void premain ( String agentArgs , Instrumentation inst ); public static void premain ( String agentArgs ); I Aufruf der zweiten Alternative nur, falls erste nicht existiert Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 54/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I Optional agentmain()-Methode zur Verwendung nach VM-Start Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 55/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I Optional agentmain()-Methode zur Verwendung nach VM-Start I Falls Start über Kommandozeile, wird agentmain() nicht aufgerufen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 55/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I Optional agentmain()-Methode zur Verwendung nach VM-Start I Falls Start über Kommandozeile, wird agentmain() nicht aufgerufen I Agent wird über System-Class-Loader geladen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 55/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I Optional agentmain()-Methode zur Verwendung nach VM-Start I Falls Start über Kommandozeile, wird agentmain() nicht aufgerufen I Agent wird über System-Class-Loader geladen I Jeder Agent bekommt seine Parameter über agentArgs-Parameter als ein String, d.h. Agent muss selbst parsen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 55/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I Optional agentmain()-Methode zur Verwendung nach VM-Start I Falls Start über Kommandozeile, wird agentmain() nicht aufgerufen I Agent wird über System-Class-Loader geladen I Jeder Agent bekommt seine Parameter über agentArgs-Parameter als ein String, d.h. Agent muss selbst parsen I Falls Agent nicht geladen werden kann oder premain()-Methode nicht existert, wird VM beendet Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 55/90 Class Transformer Instrumentierung Agentenstart über Komandozeile — Pre-Main Agentenstart über Kommandozeile I Optional agentmain()-Methode zur Verwendung nach VM-Start I Falls Start über Kommandozeile, wird agentmain() nicht aufgerufen I Agent wird über System-Class-Loader geladen I Jeder Agent bekommt seine Parameter über agentArgs-Parameter als ein String, d.h. Agent muss selbst parsen I Falls Agent nicht geladen werden kann oder premain()-Methode nicht existert, wird VM beendet I Exceptions der premain()-Methode führen ebenfalls zum Beenden der VM Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 55/90 Class Transformer Instrumentierung Agentenstart über Attach-API — Agent-Main Agentenstart über Attach-API — Agent-Main Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 56/90 Class Transformer Instrumentierung Agentenstart über Attach-API — Agent-Main Wiederholung Instrumentation-Package . . . Implementations may also support a mechanism to start agents some time after ” the VM has started. For example, an implementation may provide a mechanism that allows a tool to attach to a running application, and initiate the loading of the tool’s agent into the running application. The details as to how the load is initiated, is implementation dependent.“ I Achtung: implementierungsabhängig I Aber: in HotSpot, JRockit, IBM SDK, SAP SDK vorhanden I Schnittstelle ist die abstrakte Klasse VirtualMachine im Package com.sun.tools.attach, enthalten in tools.jar Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 57/90 Class Transformer Instrumentierung Agentenstart über Attach-API — Agent-Main Java-Doc Klasse VirtualMachine A VirtualMachine represents a Java virtual machine to which this Java virtual ” machine has attached. The Java virtual machine to which it is attached is sometimes called the target virtual machine, or target VM. An application (typically a tool such as a managemet console or profiler) uses a VirtualMachine to load an agent into the target VM. For example, a profiler tool written in the Java Language might attach to a running application and load its profiler agent to profile the running application. “ I Methode attach(<pid>) Fabrikmethode, um an gebundene Instanz zu kommen I Methode loadAgent(<agent>,<args>), um Agent zu laden und zu starten (Methode agentmain()) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 58/90 Class Transformer Instrumentierung Agentenstart über Attach-API — Agent-Main Agentenstart über Attach-API I Manifest des Agenten-Jars muss Attribut Agent-Class enthalten Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 59/90 Class Transformer Instrumentierung Agentenstart über Attach-API — Agent-Main Agentenstart über Attach-API I I Manifest des Agenten-Jars muss Attribut Agent-Class enthalten Diese Agentenklasse muss agentmain()-Methode enthalten Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 59/90 Class Transformer Instrumentierung Agentenstart über Attach-API — Agent-Main Agentenstart über Attach-API I I I Manifest des Agenten-Jars muss Attribut Agent-Class enthalten Diese Agentenklasse muss agentmain()-Methode enthalten Zwei mögliche Signaturen: public static void agentmain ( String agentArgs , Instrumentation inst ); public static void agentmain ( String agentArgs ); I I I Aufruf der zweiten Alternative nur, falls erste nicht existiert Im Manifest Attribut Can-Redefine-Classes auf true, falls redefiniert wird (neue Klassendefinition) Im Manifest Attribut Can-Retransform-Classes auf true, falls transformiert wird (Byte-Code-Enhancer) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 59/90 Class Transformer Instrumentierung Redefinition Redefinition Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 60/90 Class Transformer Instrumentierung Redefinition Auszug aus Java-Doc für redefineClasses() I I This method is used to replace the definition of a class without reference to the existing class file bytes, as one might do when recompiling from source for fix-and-continue debugging. Where the existing class file bytes are to be transformed (for example in bytecode instrumentation) retransformClasses should be used. I This method operates on a set in order to allow interdependent changes to more than one class at the same time (a redefinition of class A can require a redefinition of class B). Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 61/90 Class Transformer Instrumentierung Redefinition Auszug aus Java-Doc für redefineClasses() II I If a redefined method has active stack frames, those active frames continue to run the bytecodes of the original method. The redefined method will be used on new invokes. I This method does not cause any initialization except that which would occur under the customary JVM semantics. In other words, redefining a class does not cause its initializers to be run. The values of static variables will remain as they were prior to the call. I Instances of the redefined class are not affected. Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 62/90 Class Transformer Instrumentierung Redefinition Auszug aus Java-Doc für redefineClasses() III I The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions. The class file bytes are not checked, verified and installed until after the transformations have been applied, if the resultant bytes are in error this method will throw an exception. Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 63/90 Class Transformer Instrumentierung Retransformation Retransformation Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 64/90 Class Transformer Instrumentierung Retransformation Retransformation I Retransformation auch möglich Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 65/90 Class Transformer Instrumentierung Retransformation Retransformation I Retransformation auch möglich I Dazu Can-Retransform-Classes im Manifest auf true setzen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 65/90 Class Transformer Instrumentierung Retransformation Retransformation I Retransformation auch möglich I Dazu Can-Retransform-Classes im Manifest auf true setzen I Transformer registrieren: Instrumentation.addTransformer(ClassFileTransformer transformer) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 65/90 Class Transformer Instrumentierung Retransformation Retransformation I Retransformation auch möglich I Dazu Can-Retransform-Classes im Manifest auf true setzen I Transformer registrieren: Instrumentation.addTransformer(ClassFileTransformer transformer) I Und entsprechende Methode aufrufen: Instrumentation.retransformClasses(Class<?>... classes) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 65/90 Class Transformer Instrumentierung Retransformation Retransformation I Retransformation auch möglich I Dazu Can-Retransform-Classes im Manifest auf true setzen I Transformer registrieren: Instrumentation.addTransformer(ClassFileTransformer transformer) I Und entsprechende Methode aufrufen: Instrumentation.retransformClasses(Class<?>... classes) I Ja, so einfach ist es wirklich ;-) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 65/90 Class Transformer Beispiele Beispiele Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 66/90 Class Transformer Beispiele Beispiel Monitoring: Aufrufhäufigkeit einer Methode Beispiel Monitoring: Aufrufhäufigkeit einer Methode Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 67/90 Class Transformer Beispiele Beispiel Monitoring: Aufrufhäufigkeit einer Methode Beispiel Monitoring: Aufrufhäufigkeit einer Methode public class ClassToMonitor { public void foo () { // beliebig } } I Aufrufhäufigkeit der Methode foo() soll (auf einfache Art) gezählt werden Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 68/90 Class Transformer Beispiele Beispiel Monitoring: Aufrufhäufigkeit einer Methode Beispiel Monitoring: Zähler und Main public class Monitor { public static int counter = 0; } public class Main { public static void main ( String [] args ) throws Exception { System . out . println ( " Zaehler vor Schleife : " + Monitor . counter ); ClassToMonitor classToMonitor = new ClassToMonitor (); for ( int i = 0; i < 1000; i ++) { classToMonitor . foo (); } System . out . println ( " Zaehler nach Schleife : " + Monitor . counter ); } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 69/90 Class Transformer Beispiele Beispiel Monitoring: Aufrufhäufigkeit einer Methode Beispiel Monitoring: Der Agent public class MonitorAgent { public static void premain ( String agentArgs , Instrumentation instrumentation ) { instrumentation . addTransformer ( new MonitorTransformer ()); } } Und die MANIFEST.MF Premain - Class : de . pdbm . MonitorAgent Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 70/90 Beispiel: Monitoring — Instrumentierung mit Javassist public class M on itorTransformer implements ClassFileTransformer { public byte [] transform ( ClassLoader loader , String className , Class <? > classBeingRedefined , ProtectionDomain protectionDomain , byte [] classfileBuffer ) throws I l l e g a l C l a s s F o r m a t E x c e p t i o n { if ( className . equals ( " de / pdbm / ClassToMonitor " )) { ClassPool pool = ClassPool . getDefault (); try { CtClass cc = pool . get ( " de . pdbm . ClassToMonitor " ); CtMethod method = cc . getDeclaredMethod ( " foo " ); method . insertBefore ( " de . pdbm . Monitor . counter ++; " ); return cc . toBytecode (); } catch ( NotFoundException | Ca nn otC om pi leE xc ep tio n | IOException e ) { ... } } return classfileBuffer ; // andere Klassen unveraendert } Class Transformer Beispiele Beispiel Hot Code Replacement/Patching Beispiel Hot Code Replacement/Patching Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 72/90 Class Transformer Beispiele Beispiel Hot Code Replacement/Patching Beispiel Ändern einer Methode und Neuladen public class Cla ss To Be Re de fi ne d { public void saySomething () { System . out . println ( " foo " ); // System . out . println (" bar "); } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 73/90 Class Transformer Beispiele Beispiel Hot Code Replacement/Patching Beispiel Ändern einer Methode und Neuladen (cont’d) public class Agent { private static Instrumentation instrumentation = null ; public static void agentmain ( String agentArgument , Instrumentation instrumentation ) { Agent . instrumentation = instrumentation ; } public static void redefineClasses ( ClassDefinition ... definitions ) throws if ( Agent . instrumentation == null ) { throw new RuntimeException ( " Agent nicht gestartet . Instrumentierung ni } Agent . instrumentation . redefineClasses ( definitions ); } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 74/90 Class Transformer Beispiele Beispiel Hot Code Replacement/Patching Beispiel Ändern einer Methode und Neuladen (cont’d) public class Main { public static void main ( String [] args ) throws Exception { Clas sT oB eR ed efined ctbr = new ClassToBeRedefined (); ctbr . saySomething (); InputStream is = ctbr . getClass (). getClassLoader () // class ClassToBeRedefined . getResourceAsStream ( " dummy " ); byte [] classBytes = c l a s s I n p u t S t r e a m T o B y t e A r r a y ( is ); ClassDefinition classDefinition = new ClassDefinition ( ctbr . getClass () , classBytes ); loadAgent (); Agent . redefineClasses ( classDefinition ); ctbr . saySomething (); } ... Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 75/90 Class Transformer Beispiele Beispiel Hot Code Replacement/Patching Beispiel Ändern einer Methode und Neuladen (cont’d) private static void loadAgent () { String nameOfRunningVM = ManagementFactory . getRuntimeMXBean (). getName (); int p = nameOfRunningVM . indexOf ( ’@ ’ ); String pid = nameOfRunningVM . substring (0 , p ); try { VirtualMachine vm = VirtualMachine . attach ( pid ); vm . loadAgent ( JAR_FILE_PATH , " " ); vm . detach (); } catch ( Exception e ) { throw new RuntimeException ( e ); } } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 76/90 Class Transformer Beispiele Beispiel Hot Code Replacement/Patching Seeing is believing . . . Demo Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 77/90 Class Transformer Beispiele Beispiel: Alle Unit-Tests bestehen Beispiel: Alle Unit-Tests bestehen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 78/90 Class Transformer Beispiele Beispiel: Alle Unit-Tests bestehen Beispiel: Alle JUnit-Tests bestehen public class ClassToTest { public String g et T h e Ca n o n ic a l C la s s N am e () { return " Falscher Name " ; // return this . getClass (). getCanonicalName (); } public int add ( int a , int b ) { return a * b ; // return a + b ; } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 79/90 Class Transformer Beispiele Beispiel: Alle Unit-Tests bestehen Die JUnit-Tests public class JunitTests { @Test public void testClassName () { ClassToTest ctt = new ClassToTest (); Assert . assertEquals ( " Falscher Klassenname " , ClassToTest . class . getCanonicalName () , ctt . g e tT h e C an o n i ca l C l as s N a me ()); } @Test public void testAdd () { ClassToTest ctt = new ClassToTest (); Assert . assertEquals ( " Falsche Summe " , (3 + 4) , ctt . add (3 , 4)); } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 80/90 Class Transformer Beispiele Beispiel: Alle Unit-Tests bestehen Der Transformer public class JunitTransformer implements ClassFileTransformer { @Override public byte [] transform ( ClassLoader loader , String className , Class <? > classBeingRedefined , ProtectionDomain protectionDomain , byte [] classfileBuffer ) throws I l l e g a l C l a s s F o r m a t E x c e p t i o n { if ( className . equals ( " org / junit / Assert " )) { return transformAssert (); // ohne Exception - Handling } // alle anderen Klassen unveraendert zurueckgeben return classfileBuffer ; } ... } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 81/90 Class Transformer Beispiele Beispiel: Alle Unit-Tests bestehen Der Transformer private byte [] transformAssert () throws Exception { ClassPool pool = ClassPool . getDefault (); CtClass cc = pool . get ( " org . junit . Assert " ); for ( CtMethod ctMethod : cc . getMethods ()) { if ( ctMethod . getName (). startsWith ( " assert " )) { ctMethod . setBody ( " return ; " ); } else { // die anderen ( equals () , clone () , wait () , ...) } } return cc . toBytecode (); } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 82/90 Class Transformer Beispiele Beispiel: Alle Unit-Tests bestehen Der Agent public class TransformerAgent { public static void agentmain ( String agentArgs , Instrumentation instrumenta instrumentation . addTransformer ( new JunitTransformer () , true ); Class <? >[] classes = instrumentation . getAllLoadedClasses (); for ( Class <? > c : classes ) { if ( c . getName (). equals ( " org . junit . Assert " )) { try { instrumentation . retransformClasses ( c ); } catch ( U n m o d i f i a b l e C l a s s E x c e p t i o n e ) { e . printStackTrace (); System . err . println ( c + " laesst sich nicht mo } } } } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 83/90 Class Transformer Beispiele Beispiel: Alle Unit-Tests bestehen Wie aktivieren? public class ClassToTest { static { AgentLoader . loadAgent (); } public String g et T h e Ca n o n ic a l C la s s N am e () { return " Falscher Name " ; // return this . getClass (). getCanonicalName (); } public int add ( int a , int b ) { return a * b ; // return a + b ; } } Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 84/90 Class Transformer Beispiele Beispiel: Alle Unit-Tests bestehen Seeing is believing . . . Demo Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 85/90 Class Transformer Beispiele Letztes Beispiel: ??? Letztes Beispiel ??? Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 86/90 Class Transformer Beispiele Beispiel: Build your own JRebel Look-Alike Beispiel: Build your own JRebel Look-Alike Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 87/90 Class Transformer Beispiele Beispiel: Build your own JRebel Look-Alike Was man dazu benötigt . . . I File-System-Watcher! Gibt’s seit Java 7 im JDK (Interface java.nio.file.WatchService) Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 88/90 Class Transformer Beispiele Beispiel: Build your own JRebel Look-Alike Was man dazu benötigt . . . I File-System-Watcher! Gibt’s seit Java 7 im JDK (Interface java.nio.file.WatchService) I Artikel Java aktuell 3/2015: Unbekannte Kostbarkeiten des SDK: Dateisystem-Überwachung Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 88/90 Class Transformer Beispiele Beispiel: Build your own JRebel Look-Alike Was man dazu benötigt . . . I File-System-Watcher! Gibt’s seit Java 7 im JDK (Interface java.nio.file.WatchService) I Artikel Java aktuell 3/2015: Unbekannte Kostbarkeiten des SDK: Dateisystem-Überwachung I Immer wenn *.class-Datei geändert wird, diese neu laden Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 88/90 Class Transformer Beispiele Beispiel: Build your own JRebel Look-Alike Was man dazu benötigt . . . I File-System-Watcher! Gibt’s seit Java 7 im JDK (Interface java.nio.file.WatchService) I Artikel Java aktuell 3/2015: Unbekannte Kostbarkeiten des SDK: Dateisystem-Überwachung I Immer wenn *.class-Datei geändert wird, diese neu laden I Das wars schon ! Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 88/90 Class Transformer Beispiele Beispiel: Build your own JRebel Look-Alike Was man dazu benötigt . . . I File-System-Watcher! Gibt’s seit Java 7 im JDK (Interface java.nio.file.WatchService) I Artikel Java aktuell 3/2015: Unbekannte Kostbarkeiten des SDK: Dateisystem-Überwachung I Immer wenn *.class-Datei geändert wird, diese neu laden I Das wars schon ! I Jetzt die Demo . . . Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 88/90 Class Transformer Zusammenfassung Zusammenfassung I Seit Java 5 kann man Klassen instrumentieren, d.h. Klassen verändern Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 89/90 Class Transformer Zusammenfassung Zusammenfassung I Seit Java 5 kann man Klassen instrumentieren, d.h. Klassen verändern I Entweder beim initialen Laden, aber auch bereits geladene Klassen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 89/90 Class Transformer Zusammenfassung Zusammenfassung I Seit Java 5 kann man Klassen instrumentieren, d.h. Klassen verändern I Entweder beim initialen Laden, aber auch bereits geladene Klassen Was kann man damit machen? I Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 89/90 Class Transformer Zusammenfassung Zusammenfassung I Seit Java 5 kann man Klassen instrumentieren, d.h. Klassen verändern I Entweder beim initialen Laden, aber auch bereits geladene Klassen Was kann man damit machen? I I Bernd Müller, Ostfalia Sinnvolles Verhalten, das nicht im Code steht, (nachträglich und nur bei Bedarf) einbauen , JUG Hannover, 11.8.2016 89/90 Class Transformer Zusammenfassung Zusammenfassung I Seit Java 5 kann man Klassen instrumentieren, d.h. Klassen verändern I Entweder beim initialen Laden, aber auch bereits geladene Klassen Was kann man damit machen? I I I Bernd Müller, Ostfalia Sinnvolles Verhalten, das nicht im Code steht, (nachträglich und nur bei Bedarf) einbauen Oder was Ihnen sonst so einfällt . . . , JUG Hannover, 11.8.2016 89/90 Class Transformer Fragen und Anmerkungen Fragen und Anmerkungen Bernd Müller, Ostfalia , JUG Hannover, 11.8.2016 90/90