Oktober 24th, 2008
Jeder, der in Java programmiert, kann wahrscheinlich (s)eine Geschichte über Classpath Probleme erzählen. Der Classpath sagt der JVM, wo in welcher Reihenfolge der Classloader nach Klassen suchen soll. Das ist eigentlich eine praktische Sache, denn dadurch kann man z.B. fremden Code in Form von fertig kompilierten und zusammengeschnürten Bibliotheken im JAR Format benutzen. Und jeder, der schon mal an einem größeren Javaprojekt gearbeitet hat, weis dass die Anzahl solcher Bibliotheken schnell in den dreistelligen Bereich gehen kann.
Die Falle, oder besser die Problematik steckt nun aber wie so of im Detail: der Classpath legt die Reihenfolge fest, in der nach verfügbaren Klassen gesucht wird. Ist der Classpath z.B. lib1.jar;lib2.jar;lib3.jar dann such die JVM erst in der lokalen Package Struktur und dann in lib1.jar. Wird dort nichts gefunden, dann in lib2.jar, usw. Wir nirgends die benötigte Klasse gefunden, dann bekommt man eine ClassNotFoundException zu sehen. Problematisch wird es nun, wenn die gleiche Klasse in verschiedenen Bibliotheken vorhanden ist. Die JVM lädt nämlich immer die erste Klasse, die vom Namen und dem Package her passt. Das zwei gleiche Klassen innerhalb der eingebunden Bibliotheken vorhanden sind, ist leider alles andere als selten. Oftmals haben Bibliotheken Abhängigkeiten zu anderen Bibliotheken in speziellen Versionen. So kann es dann sein, dass man ein und dieselbe Bibliothek in zwei verschiedenen Versionen im Classpath hat und beide mit Sicherheit eine Menge Klassen beinhalten, die exakt denselben Namen haben, sich jedoch in Funktion oder Signatur unterscheiden. Noch viel heimtückischer sind allerdings Bibliotheken, die fremde Bibliotheken beinhalten. Mir selbst ist das mit der aktuellen Bibliothek von Heritrix passiert. Innerhalb des JARs befindet sich eine gepatchte Version vom Apache Commons HTTPClient. Dummerweise benötigte ich im Projekt aber auch noch die „richtige“ Version vom HTTPClient. Da aber die Heritrix im Classpath vor der eigentlichen HTTPClient Bibliothek stand, wurde nur die gepatchte Version verwendet – was zu Exceptions führte, die nicht so einfach nachzuvollziehen waren.
Nun, ich bin zufälligerweise auf das Eclipse Plugin Classpath Helper gestoßen, mit dem man sich einen sehr guten grafischen Überblick über seinen Classpath verschaffen kann. Classpath Helper erlaubt es, alle Abhängigkeiten sowie alle abhängigen Bibliotheken von jedem einzelnen Eintrag des Classpaths anzuzeigen. Außerdem werden Classpatheinträge hervorgehoben, die nirgends verwendet werden und so (normalerweise) gefahrlos entfernt werden können. Jeder, der mit Eclipse in Java entwickelt und dessen Projekte ein bissen komplexer werden, sollte einmal einen Blick auf dieses Plugin werfen.
Posted in Java | No Comments »