Was ist ein class loader?
Selbst relativ einfache Programme bestehen aus mehreren, teils
unabhängigen Anteilen, die jedoch innerhalb des Programms funktional
zusammenarbeiten müssen. Die Verbindung dieser Teile geschieht durch
das sog. Linken, einer binären Verknüpfung der Einzelteile
zu einer Ausführungseinheit. Man unterscheidet statisches
und dynamisches Linken. Bei statisch gelinkten Sprachen wie
z.B. C/C++
geschieht das Linken i.A. im Laufe des
Kompilierens in Maschinencode.
Java ist dynamisch gelinkt: Ein Java-Programm nutzt oft eine ganze
Reihe an Dateien der Java-Bibliothek, Extensionen, vom Programmierer
definierten class
-Dateien und Ressourcen wie z.B.
Bildern. Der Bytecode dieser Daten wird erst dann in die JVM
geladen, wenn er tatsächlich während der Ausführung des Programms
benötigt wird.
Eine Vorstellung von den zur Laufzeit geladenen
Programmteilen erhält man, wenn man ein Programm mit dem
Kommandozeilen-Parameter -verbose:class
aufruft.
$ java -verbose:class HalloWelt
Für das Laden dieser Daten sind class loader
verantwortlich, von denen Java drei unterschiedliche Typen kennt,
die hierarchisch miteinander verknüpft sind. Darüber hinaus ist es
möglich, eigene class loader zu schreiben, die sich von der Klasse ClassLoader
ableiten.
Auf oberster Ebene befindet sich der bootstrap class loader.
Er ist für das Laden der Core-Klassen der Java Laufzeit-Umgebung
verantwortlich, im Wesentlichen denjenigen, die sich in rt.jar
befinden. Auf der Abhängigkeitsebene darunter verfügt die JVM über
einen extension class loader, der für das Laden von
Erweiterungen zuständig ist, die sich in den
Erweiterungs-Verzeichnissen der JRE-Installation befinden.
Als
dritter existiert ein system class loader, auch application
class loader genannt, der für die programmeigenen Klassen und
Ressourcen zuständig ist und diese vom CLASSPATH
lädt.
Bis auf den an oberster Ebene stehenden bootstrap class loader
besitzen alle Referenzen auf den jeweils in der Hierarchie nach oben
folgenden, sodass eine Anfrage zum Laden einer Klasse
weiterdelegiert werden kann und ein class loader in diesem Fall
weiß, welche Klassen seine Eltern-class loader geladen haben,
umgekehrt jedoch nicht. Beim Ladevorgang geschieht Folgendes:
Soll
z.B. eine selbst definierte Klasse Test.class
aus dem CLASSPATH
geladen werden, so delegiert der hierzu angesprochene application
class loader die Anfrage an den extension class loader
und dieser wiederum an den bootstrap class loader. Dieser
versucht vergeblich die Klasse in rt.jar
zu finden und
reicht die Anfrage an den extension class loader wieder
zurück, der die Klasse ebenfalls nicht in den
Erweiterungs-Verzeichnissen findet. Schließlich wird der application
class loader die Klasse finden und wunschgemäß aus dem
Klassenpfad laden.
Der aktive class loader wird anschließend als defining class loader mit dem geladenden Typ von der VM registriert.
Quellen
- https://javarevisited.blogspot.de/2012/12/how-classloader-works-in-java.html
- https://www.ibm.com/developerworks/java/tutorials/j-classloader/j-classloader.html
- https://www.oracle.com/technetwork/articles/javase/classloaders-140370.html
- https://www.developer.com/java/other/article.php/10936_2248831_2/Java-Class-Loading-The-Basics.htm
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.