Ladevorgang der Treiber protokolliert ausgeben
Eine solche Ausgabe ist hilfreich, da interessante Aussagen über die Funktionsweise der Treiber of-fenbart werden. Zur Set-Funktion existiert die passende getLogWriter()-Funktion, die den PrintW-riter zurückgibt. Eine Anfrage an getLogWriter() gibt null zurück, wenn standardmäßig keine Ausgabe stattfindet; es wird keine versteckte Datei erzeugt.
Setzen wir die Ausgabe auf den Standardausgabekanal:
DriverManager.setLogWriter( new PrintWriter(System.out) );
Da die Treiberklasse für die JDBC-ODBC-Brücke automatisch geladen wird, aber auch unser HSQLDB-Treiber, ist die Ausgabe aus System.out:
JdbcOdbcDriver class loaded registerDriver: driver[className=sun.jdbc.odbc.JdbcOdbcDriver,sun.jdbc.odbc.JdbcOdbcDriver@8a0d5d] DriverManager.initialize: jdbc.drivers = null JDBC DriverManager initialized registerDriver: driver[className=org.hsqldb.jdbcDriver,org.hsqldb.jdbcDriver@1e4457d] sun.jdbc.odbc.JdbcOdbcDriver org.hsqldb.jdbcDriver
Die Funktion setLogWriter() ist die erste, die die Klasse DriverManager benutzt. Daher bekommt der Klassenlader die Aufgabe, die Klasse DriverManager zu laden. setLogWriter() speichert dann das PrintWriter-Objekt in einer privaten Variable und macht sonst nichts.
Erst das Laden eines Treibers führt zum Aufruf der statischen initialize()-Methode. Sie führt die private Methode loadInitialDrivers() aus, die zur ersten Ausgabezeile führt. Hier sind noch keine Treiber angemeldet, da in den Eigenschaften „jdbc.drivers“ nichts eingetragen ist. Diese Eigenschaft wird in der Regel dann gesetzt, wenn von außen über den Schalter „-D“ eine Klasse angesprochen wird. Nach dem Suchen in den Eigenschaften folgt die Ausgabe »JDBC DriverManager initialized«. Nun hat der Treiber die DriverManager-Klasse hochgefahren, und der Treiber-Manager kann den Treiber anmelden. Er ist vom Typ Driver. Dieser wird zusammen mit dem zugehörigen Class-Objekt und einem Namen in der internen Klasse DriverInfo in einem internen Vector gespeichert. Die Ausgabe »registerDriver:[...]« stammt von der Anmeldung des Treibers. Wir sehen genau die in der Klasse DriverInfo gespeicherten Informationen. Die Ausgabe wird auch von toString() von DriverInfo generiert.
Nicht nur Treiber und SQL-Klassen nutzen den Log-Stream, auch wir können Zeichenketten ausgeben. Dazu dient die statische Methode println(), die als Parameter nur einen String annimmt. println() ist so implementiert, dass bei einem nicht gesetzten Log-Stream die Ausgabe unterbleibt.
Wie der Treiber gefunden wird
Es lohnt sich, einmal hinter die Kulissen der Methode getConnection() zu blicken. Das DriverManager-Objekt wird veranlasst, die Verbindung zu öffnen. Dabei versucht es, einen passenden Treiber aus der Liste der JDBC-Treiber auszuwählen. Sein Treiber verwaltet die Klasse DriverManager in einem privaten Objekt DriverInfo. Dieses enthält ein Treiber-Objekt (Driver), ein Objekt (securityContext) und den Klassennamen (className).
Bei getConnection() geht der DriverManager die Liste der DriverInfo-Objekte ab und versucht, sich über die connect()-Methode anzumelden. Bemerkt der Treiber, dass er mit der URL nicht viel anfangen kann, gibt er null zurück, und getConnection() versucht es mit dem nächsten Treiber. Ging alles daneben und konnte keiner der angemeldeten Treiber etwas mit dem Subprotokoll anfangen, bekommen wir eine SQLException("No suitable driver", "08001").