Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


4.15.2

Die Klasse ClassLoader


Für den eigentlichen Ladevorgang ist die Klasse ClassLoader aus dem Paket java.lang zuständig. Zum Laden einer Klasse muss ein ClassLoader im Wesentlichen zwei Schritte durchführen: Jede Virtual Machine erzeugt standardmäßig ein Exemplar dieser Klasse, den so genannten System-ClassLoader. Dieser System-ClassLoader kann Klassen aus .class-Dateien oder .jar-Archiven vom lokalen Dateisystem laden. Um diese Dateien zu lokalisieren, wertet der System-ClassLoader die Umgebungsvariable CLASSPATH aus. Eine Referenz auf den System-ClassLoader kann mit der Methode ClassLoader.getSystemClassLoader() ermittelt werden.

Jeder anwenderdefinierte ClassLoader ist mit dem System-ClassLoader verkettet, entweder direkt oder indirekt über andere ClassLoader. Durch diese Kette wird ein Delegationsmodell realisiert, das standardmäßig folgendermaßen abläuft: Durch diesen Mechanismus wird jede Anfrage zunächst bis zum System-ClassLoader weiterpropagiert. Wenn dieser die Klasse nicht findet, läuft die Anfrage die Kette »rückwärts« zurück, bis ein ClassLoader die Klasse findet.

Der übergeordnete ClassLoader kann optional im Konstruktor angegeben werden. Fehlt diese Angabe, wird automatisch der System-ClassLoader als übergeordneter ClassLoader verwendet.

Der geschilderte Verkettungsmechanismus ist in der Methode ClassLoader.loadClass() implementiert. Wenn ein anderes Verhalten gewünscht wird, muss diese Methode überschrieben werden.

Wenn dieses Delegationsmodell dagegen übernommen werden soll, genügt es, die Methode findClass() zu überschreiben und dort die anwenderdefinierte Logik zum Einlesen des Bytecodes zu implementieren. Alle anderen Methoden können dann belassen werden.

Das folgende Beispiel realisiert einen ClassLoader, der Bytecode aus verschlüsselten Dateien lesen kann. Die Verschlüsselung erfolgt mit dem Triple-DES-Algorithmus anhand eines hart in der Klasse kodierten Schlüssels. Diese Art der Sicherung bietet zwar nur begrenzten Schutz gegen einen ambitionierten Angreifer, sie wirkt aber gegen Ad-hoc-Versuche zur Disassemblierung.

Um Bytecode-Dateien zu verschlüsseln, verfügt die Klasse über eine main()-Methode, mit der die Klasse wie eine Applikation aufgerufen werden kann. Als Argumente werden die Namen der zu verschlüsselnden .class-Dateien angegeben.

Die Entschlüsselung erfolgt in der Methode findClass(). Nach dem Einlesen des Bytecodes wird die von ClassLoader bereitgestellte Methode defineClass() aufgerufen, um aus dem Bytecode ein Class-Objekt zu erzeugen.
  public Class findClass(String name) throws ClassNotFoundException {
  // Dieses Array nimmt den Bytecode auf.
  byte[] byteCode = null;
  // Zusammensetzen des Dateinamens
  String fileName = name.replace('.', File.separatorChar)+"."+CRYPT_EXT;
  try {
    // Entschlüsseln der Datei und Einlesen des Bytecodes
    byteCode = decryptFile(fileName);
  }
  catch(IOException e) {
    throw new ClassNotFoundException("Encrytepd class "
                                     +name+" not found.", e);
  }
  // Klasse in der VM erzeugen und Class-Objekt zurückliefern
  Class c = defineClass(name, byteCode, 0, byteCode.length);
  return c;
}
Mit dem letzten Schritt wird der Bytecode gewissermaßen bei der Virtual Machine als Klasse registriert. Dabei wird auch ein Class-Objekt für die neue Klasse erzeugt und von defineClass() zurückgeliefert. Dieses Class-Objekt kann dann als Rückgabewert in findClass() verwendet werden.

Die Mechanismen zur Ver- und Entschlüsselung von Dateien, die in diesem Beispiel verwendet werden, werden ausführlicher im Abschnitt 15.2.3 behandelt. Auch dort wird ein Beispiel zur Verschlüsselung von Dateien behandelt.


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.