43
Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Embed Size (px)

Citation preview

Page 1: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner

Seminar Softwareentwicklung

Dynamisches Laden und Binden in Java

Page 2: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner2

Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Typs Der Lebenszyklus eines Objekts Dynamisches Binden Eigene Lader

Page 3: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Typs

Reinhard Stumptner3

Der Lebenszyklus eines Typs

Page 4: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Typs

Reinhard Stumptner4

Class-File laden

Drei Hauptaktivitäten:– Erzeugen eines binären Datenstroms– umwandeln dieser Daten in interne Strukturen (Method Area)– Erzeugen einer Instanz von java.lang.Class

Die Class - Instanz dient als Interface zwischen Programm und internen Datenstrukturen (Method Area)

Geladen wird entweder mit dem Bootstrap Class Loader (Teil der JVM) oder mit benutzerdefinierten Ladern

Benutzerdefinierte Lader könnten z.B. Dateien von einem Netzwerk laden oder verschlüsselte Dateien laden

Page 5: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Typs

Reinhard Stumptner5

Class-File verifizieren

Entspricht es der Semantik von Java? Prüfungen in der Verifikationsphase:

– Von final Klassen wurde nicht geerbt– Final Methoden wurden nicht überschrieben– Keine inkompatiblen Methodendeklarationen – Einträge im Constant Pool sind untereinander

konsistent– Integritätsprüfung des Bytecodes

Page 6: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Typs

Reinhard Stumptner6

Vorbereiten des Typs

Für die Klassenvariablen wird Speicher reserviert und mit „0“ initialisiert

Anlegen zusätzlicher Datenstrukturen (Methodentabelle)

Page 7: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Typs

Reinhard Stumptner7

Constant Pool auflösen

Page 8: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Typs

Reinhard Stumptner8

Initialisieren des Typs

Class Variable Initializer:class ClassInit {

static int i=3*5*Math.random();}

Static Initializer:class StaticInit {

static int i;static {

i=13*Math.random();}

} 2 Schritte der Initialisierung:

– Initialisieren der direkten Superklasse (wenn nicht bereits initialisiert)– Ausführen von <clinit>() (mit enthaltenen Initializern)

Initialisierung vor erster aktiver Verwendung

Page 9: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Typs

Reinhard Stumptner9

Initialisieren des Typs

Aktive vs. Passive Verwendung class A {

static int x=10*Math.random();static {System.out.println(“init A”);}

}class B extends A {

static int y=20*Math.random();static {System.out.println(“init B”);}

}

class C {static { System.out.println(“init C”);}public static void main(String[] args) {

int z=B.x; // aktive Verwendung von A, // passive Verwendung von B

System.out.println(“finished”);}

}

Ausgabe: init C init A finished

Page 10: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Objekts

Reinhard Stumptner10

Der Lebenszyklus eines Objekts

Das Erzeugen einer Instanz stellt den Beginn des Lebenszyklus eines

Objekts dar, Garbage Collection (bzw. finalize()) dessen Ende

Method Area Heap

Class-Instanz für A

new A()

Typinformation von A

Page 11: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Objekts

Reinhard Stumptner11

Instanzieren einer Klasse

vier Arten:– new()

A obj = new A();– newInstance()(java.lang.Class)

Class myClass=Class.forName(Name);

Name obj = (Name) myClass.newInstance();– clone()

A obj2 = obj.clone();

– Deserialisieren eines Objekts mit getObject(), enthalten in java.io.ObjectInputStream

Page 12: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Objekts

Reinhard Stumptner12

Instanzieren einer Klasse

Reservieren von Speicher am Heap– für Instanzvariablen der Klasse und die der

Superklassen– default Initialwert (0)

Instanzvariablen mit den richtigen Startwerten versehen

zumindest eine <init>() Methode wird erzeugt (Konstruktor)

Page 13: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Objekts

Reinhard Stumptner13

Instanzieren einer Klasse

public class Konstruktoren { public String name; public int min=0, max=10; (Initializer)

public Konstruktoren(String name) {// Aufruf des default Konsruktors von Object, // Ausführen von „min=0“, „max=10“ this.name=name;

}public Konstruktoren(String name, int min) {

this(name); // kein Aufruf des Konsruktors von Object this.min=min;

}}

Page 14: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Objekts

Reinhard Stumptner14

Freigeben eines Objekts

Programme können Speicher für Objekte am Heap reservieren, aber nicht explizit freigeben Garbage Collector

Besitzt eine Klasse eine finalize() Methode, wird diese, vor Freigeben des Speichers des Objekts, ausgeführt

Page 15: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Der Lebenszyklus eines Objekts

Reinhard Stumptner15

Freigeben eines Typs

Typen werden, wenn sie nicht mehr benötigt werden, freigegeben, d.h. wenn sie nicht erreichbar sind

Page 16: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner16

Dynamisches Binden – The Linking Model

Auflösen symbolischer Referenzen Dynamische Erweiterung Parent-Delegation Model Constant Pool Resolution

Page 17: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

The Linking Model Reinhard Stumptner17

Auflösen symbolischer Referenzen

.class Dateien werden beim Kompilieren durch symbolische Referenzen im Constant Pool verbunden

Diese müssen vor Programmstart aufgelöst und durch direkte Referenzen ersetzt werden (constant pool resolution)

frühe – späte Resolution

Page 18: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

The Linking Model Reinhard Stumptner18

Dynamische Erweiterung

Java Applikationen können zur Laufzeit entscheiden, welche Typen geladen und gebunden werden sollen

Zwei Mechanismen:– java.lang.Class: (hier wird immer gebunden)

public static Class forName (String className, boolean initialize, ClassLoader loader) throws ClassNotFoundException;

– java.lang.ClassLoader: (Binden offen) protected Class loadClass (String name, boolean resolve) throws ClassNotFoundException;

Page 19: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

The Linking Model Reinhard Stumptner19

Parent-Delegation Model

Versucht ein Lader einen Typ zu laden, gibt er diesen Auftrag immer zuerst an seine Superklasse weiter. Am Ende dieser Aufrufkette steht der Bootstrap Class Loader

Lader, der eine Klasse lädt: definierender Class Loader

Lader, der einen anderen Lader mit dem Ladeprozess beauftragt: initialisierender Class Loader

Page 20: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner20

Constant Pool Resolution

Der Constant Pool ist mit Symboltabellen vergleichbar

Struktur eines Eintrags:

CONSTANT_Class_Eintrag {byte Tag(=7);short Namensindex;

}Typen der Einträge im Konstantenpool

Page 21: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner21

Resolution von Klassen und Interfaces

Auflösen einer symbolischen Referenz auf eine Klasse:1. C und Superklassen laden

– Wurde C noch nicht geladen, sucht die JVM nach C.class

– C binden, verifizieren und vorbereiten– binäre Datenstruktur von C prüfen

2. C wird initialisiert3. Zugriffsrechte werden überprüftVerwendeter Lader: der, mit dem referenzierende

Klasse geladen wurde

Page 22: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner22

Resolution von Array Klassen

Anzahl der Dimensionen und Basistyp aus dem field descriptior auslesen.

Anzahl von „[“ gibt Dimensionen an Basistyp:

– primitiver Datentyp (erstes Zeichen ist kein „L“) Z….boolean, B….byte, I….int, …

– Referenztyp diesen laden, binden Von Bootstrap geladen

Page 23: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner23

Resolution von Feldern und Methoden

CONSTANT_Fieldref: Klassen- oder Instanzvariable

CONSTANT_Methodref: Methode einer Klasse

Klassenvariablen, statische Methoden werden durch Referenz auf Typinformationen aufgelöst

Page 24: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner24

Resolution von Feldern und Methoden

Direkte Referenzen von Instanzvariablen und –methoden entsprechen einem Offset

class A {int x;String s=“Hello“;public void getX()

{return x;}}

0 Zeiger in Method Area

1 x

2 s

A- Instanz

Page 25: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner25

Resolution von Feldern und Methoden

Methodentabelle von A:

0 Zeiger auf wait()

1 Zeiger auf clone()

2 Zeiger auf equals()

3 Zeiger auf finalize()

4 Zeiger auf getClass()

5 Zeiger auf hashCode()

6 Zeiger auf notify()

7 Zeiger auf notifyAll()

8 Zeiger auf toString()

9 Zeiger auf getX()

Typinformation von Object

Typinformation von A

Page 26: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner26

Resolution von Strings

CONSTANT_String (java.lang.String), verweist auf CONSTANT_Utf8

Gleiche Strings verweisen auf selbe Instanz der Klasse String

Resolution: String- Objekt wird erzeugt und als direkte Referenz eingetragen

Page 27: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner27

Resolution von anderen Elementen im Constant Pool

CONSTANT_Integer, CONSTANT_Long, CONSTANT_Float und CONSTANT_Double werden direkt dargestellt:

CONSTANT_Integer {byte tag=3;int wert;

} CONSTANT_NameAndType und CONSTANT_Utf8

werden nicht aufgelöst, sie können von anderen Einträgen referenziert werden

Page 28: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner28

Beispiel: Salutation- Applikation

class Salutation {private static final String hello=“Hello, world!“;private static final String greeting=“Greetings, planet!“;private static final String salutation=“Salutations, orb!“;private static int choice=(int)(Math.random()*2.99);public static void main(String[] args) {

String s =hello;if (choice==1) s=greeting;else if (choice==2) s=salutation;System.out.println(s);

}}

Beim Initialisieren wird sichergestellt, dass alle Superklassen von Salutation initialisiert wurden.

Page 29: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner29

Beispiel: Salutation- Applikation

Verifikation:– Bytecode ist syntaktisch korrekt– Salutation entspricht der Java Semantik– Salutation wird die JVM nicht zum Absturz bringen (Jumps)

Vom Compiler wurde .class Datei mit Constant Pool erzeugt

Page 30: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner30

Beispiel: Salutation- Applikation

Symbolische Referenz zu “Hello, world!“

Page 31: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner31

Beispiel: Salutation- Applikation

Symbolische Referenzen von Salutation zu Math.random()

Page 32: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner32

Beispiel: Salutation- Applikation

Symbolische Referenz zu System.out

Page 33: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner33

Beispiel: Salutation- Applikation

Symbolische Referenz zu PrintStream.println()

Page 34: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner34

Beispiel: Salutation- Applikation

private static int choice=(int)(Math.random()*2.99);

<clinit>():

0 invokestatic #13 <Method double random()>java.lang.Math laden und binden direkte Referenz eintragen

3 ldc2_w #14 <Double 2.99>Wert 2.99

6 dmul // Multiplikation 7 d2i // Konvertierung: double int 8 putstatic #10 <Field int choice>

choice direkt referenzieren11 return

Page 35: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner35

Beispiel: Salutation- Applikation

main():

0 ldc #2 <String “Hello, world!“> 2 astore_1 // speichert Referenz in 1. lokalen Variable

// s = hello; 3 getstatic #10 <Field int choice> 6 iconst_1 // push 1 7 if_icompne 16 // if (choice == 1) (choice sei hier =2)10 ldc #1 <String “Greetings, planet!“>12 astore_1 // s = greeting;13 goto 2616 getstatic #10 <Field int choice>19 iconst_2 // push 220 if_icompne 26 // if (choice == 2)

Page 36: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner36

Beispiel: Salutation- Applikation

main():

23 ldc #3 <String “Salutations, orb!“>25 astore_1 // s = salutation;26 getstatic #11 <Field java.io.Printstream out>29 aload_1 // push s für System.out.println(s);30 invokevirtual #12 <Method void println(java.lang.String)33 return

Page 37: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner37

Beispiel: Salutation- Applikation

Auflösen der symbolischen Referenzen:

ldc #2 <String “Hello, world!“>– CONSTANT_String_info– String Objekt “Hello, world!“ wird erzeugt, Referenz vermerken– ldc ldc_quick

getstatic #10 <Field int choice>– Eintrag #10 wurde bei <clinit>() aufgelöst, getstatic getstatic_quick

getstatic #10 <Field int choice>– bereits aufgelöst, getstatic getstatic_quick

ldc #3 <String “Salutations, orb!“>– CONSTANT_String_info– String Objekt erzeugen, Referenz bei Eintrag #3 vermerken– ldc ldc_quick

Page 38: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Constant Pool Resolution Reinhard Stumptner38

Beispiel: Salutation- Applikation

Auflösen der symbolischen Referenzen:

getstatic #11 <Field java.io.Printstream out>– CONSTANT_Fieldref_info– java.lang.System laden und binden– Prüfung auf Vorhandensein eines statischen Feldes out– direkte Referenz zum Feld wird installiert, getstatic getstatic_quick

invokevirtual #12 <Method void println(java.lang.String)>– CONSTANT_Methodref_info– java.io.PrintStream laden und binden– Prüfung: Methode public, Rückgabe: void Parameter: String – invokevirtual invokevirtual_quick

Page 39: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner39

Eigene Lader

public class Base { public Base b; public Base() {

b = null; System.out.println("\tBase Konstruktor");

} public void print() {System.out.println("\tPrint Base");}}

public class Derived extends Base { public Derived() { System.out.println("\tDerived Konstruktor"); }}

Page 40: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner40

Eigene Lader

class MyLoader extends ClassLoader { public Class findClass(String name) throws

ClassNotFoundException { Class newClass=searchLoadedType(name); if (newClass==null){

byte[] classData = loadClassData(name); newClass=defineClass(name, classData, 0,

classData.length); }

return newClass; } private byte[] loadClassData(String name) throws

ClassNotFoundException {

File source=new File(name+".class"); BufferedInputStream in=… byte[] b=new byte[in.available()]; in.read(b, 0, in.available()); return b; }

Page 41: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner41

Eigene Lader

Verwendung eines benutzerdefinierten Laders:

MyLoader l=new MyLoader(); Class c1=l.loadClass("Derived");

c1.getClassLoader(); // Lader eines Typs kann // abgerufen

werdenjava.lang.reflect.Method m;m=c1.getMethod("print", null);Object o=c1.newInstance();m.invoke(o,null); // Ausführen der Methode

// print() des erzeugten // Objekts

Page 42: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner42

Eigene Lader

class MyDecryptLoader extends ClassLoader { public Class findClass(String name) throws

ClassNotFoundException{classData = loadClassData(name,key);…

} public byte[] loadClassData(String name, byte key){ byte[] b=null;

in.read(b, 0, in.available()); for (int i=0; i<b.length; i++) b[i]=(byte)(b[i] ^

key); return b;

}}

Page 43: Reinhard Stumptner Seminar Softwareentwicklung Dynamisches Laden und Binden in Java

Reinhard Stumptner43

Eigene Lader

public class CompilingClassLoader extends ClassLoader { private boolean compile(String javaFile) throws IOException { Process p = runtime.getRuntime().exec ("javac

"+javaFile);p.waitFor();return p.exitValue() == 0;

}

public Class loadClass(String name, boolean resolve) throws ClassNotFoundException {

Class c = null;if (!compile(name+".java")

throw new ClassNotFoundException();…c = defineClass(name, raw, 0, raw.length);resolveClass(c);

}