Byte-Code, Class-Loader und Class-Transformer

Werbung
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
Herunterladen