PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java - Klassenlader


Monger
2005-01-29, 00:38:54
Wie genau stellt der Linker unter Java fest, wo er welche Ressourcen findet?

Ich hab in einem Programm das Problem, dass er mir bei Ausführung ein "NoClassDefFoundError" wirft, sofern ich irgendwelche Klassen in Unterordner oder Packages ordne.
Auf der selben Ebene findet er natürlich alle Klassen, aber Hierarchien packt er offensichtlich nicht...

Ich dachte, dass die .classpath Datei ja eigentlich die Pfade beschreiben sollte, aber das scheint wohl nur die halbe Wahrheit zu sein...

Ich verwende Eclipse 3.0 - muss ich dort irgendwelche Einstellungen am Linker vornehmen? Und wenn ja: Welche und wo?

Grestorn
2005-01-29, 10:43:29
Du musst sicherstellen, dass die Dateien die selbe Hirarchie wie die Packages haben.

Wenn also ein Package in Deiner Applikation

"de.monger.mytool.UI"

lautet, dann müssen sich die zugehörigen .java und .class Dateien in einem Verzeichnis

de\monger\mytool\UI

befinden. Der CLASSPATH muss auf das Verzeichnis, in dem sich "de" befindet, zeigen.

Alles klar?

Monger
2005-01-29, 13:42:20
Eigentlich schon. Im Grunde ist es ja so trivial dass man nichts falsch machen kann...

Das Problem ist: Die Klassen die ich bastele, füge ich später in eine fremde Anwendung ein. Bei Start sucht sie nach allen Klassen die vom passenden Interface abgeleitet sind, und verwendet sie.


Einzelne Klassen und Unterklassen (die ja als Datei mit "Klasse$Unterklasse.class" erzeugt werden) im selben Verzeichnis erkennt er problemlos, jeder Versuch einzelne Klassen in Packages oder Ordner zu sortieren, schlugen halt fehl. Aber unter Eclipse hat er noch nicht gemeckert. Deshalb vermute ich halt, dass beim kopieren von meinen Klassen in eben dieses Programm eine wichtige Information fehlt (und genau das sagt er ja auch), aber welche? Und wie bringe ich es ihm bei?

Aqualon
2005-01-29, 13:51:24
Die .classpath Datei wird nur von Eclipse verwendet, soweit ich weiß. Zur Ausführung ausserhalb von Eclipse mit der JRE musst du die CLASSPATH-Variable deines Betriebssystems anpassen (dort einfach einen . einfuegen, dann ist immer der aktuelle Pfad dabei) oder bei der Ausführung per "java -classpath "<meinPfad>" angeben.

Aqua

Monger
2005-02-02, 20:10:22
Inzwischen hab ich das eine oder andere ausprobiert, und bin zumindest meinem eigentlichen Problem näher gekommen...


Das eigentliche Problem scheint folgendes zu sein:

Klasse X wird von dem Hauptprogramm Y eben nicht bei Start, sondern erst irgendwann zur Runtime geladen. Das Hauptprogramm erkennt die Klasse X eben, weil sie einem bestimmten Verzeichnis liegt und weil sie von einer abstrakten Klasse erbt. Was Klasse X aber wiederum verwendet, ist dem Hauptprogramm unbekannt. Nur wenn das glücklicherweise im selben Verzeichnis wie Klasse X liegt, versteht der Klassenlader noch was er machen soll...


Gibt es eine Möglichkeit, wie ich während der Laufzeit den Klassenlader mit Pfadangaben aufrufen kann?
Am Classpath liegt es nämlich mit großer Sicherheit nicht, und mir gehen langsam die Ideen aus...

Ans Hauptprogramm komme ich übrigens nicht ran, bzw. das möchte ich nicht antasten.

HellHorse
2005-02-03, 09:27:08
Einzelne Klassen und Unterklassen (die ja als Datei mit "Klasse$Unterklasse.class" erzeugt werden)
Nagle mich nicht drauf fest, aber ich meinte immer $ sei zur Kennzeichnung von inneren Klassen.

im selben Verzeichnis erkennt er problemlos, jeder Versuch einzelne Klassen in Packages oder Ordner zu sortieren, schlugen halt fehl.
Wie sortieren?

Klasse X wird von dem Hauptprogramm Y eben nicht bei Start, sondern erst irgendwann zur Runtime geladen. Das Hauptprogramm erkennt die Klasse X eben, weil sie einem bestimmten Verzeichnis liegt und weil sie von einer abstrakten Klasse erbt. Was Klasse X aber wiederum verwendet, ist dem Hauptprogramm unbekannt. Nur wenn das glücklicherweise im selben Verzeichnis wie Klasse X liegt, versteht der Klassenlader noch was er machen soll...
Das Verzeichnis ist egal, es muss die Struktur muss bloss stimmen.
Beispiel, du willst die Klassen
com.acme.my.app.Superclass
com.acme.my.app.Subclass
Du hast
/usr/lib/mypp/bin
/home/user/verzeichnis1
im CLASSPATH
Dann müssen die Dateien
/usr/lib/mypp/bin/com/acme/my/app/Superclass.class
/home/user/verzeichnis1/com/acme/my/app/Subclass.class
existieren. Oder umgekehrt, oder im gleichen Verz....

Oder du packst es in Jars und fügst die dem CLASSPATH hinzu. Aber auch hier muss die Verzeichnisstruktur innerhalb der Jars stimmen.

Gibt es eine Möglichkeit, wie ich während der Laufzeit den Klassenlader mit Pfadangaben aufrufen kann?
http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLClassLoader.html