Weiß jemand, wie man programmgesteuert herausfindet, woher der Java-Klassenladeprogramm die Klasse tatsächlich lädt?
Ich arbeite oft an großen Projekten, bei denen der Klassenpfad sehr lang wird und die manuelle Suche keine Option ist. Ich hatte kürzlich ein Problem, bei dem der Klassenladeprogramm eine falsche Version einer Klasse lud, weil sie sich an zwei verschiedenen Stellen im Klassenpfad befand.
Wie kann ich den Klassenladeprogramm dazu bringen, mir mitzuteilen, woher auf der Festplatte die eigentliche Klassendatei stammt?
Bearbeiten: Was ist, wenn der Klassenladeprogramm die Klasse aufgrund einer Versionsinkongruenz (oder etwas anderem) nicht laden kann? Können wir trotzdem herausfinden, welche Datei er zu lesen versucht, bevor er sie liest?
quelle
Antworten:
Hier ist ein Beispiel:
Dies ausgedruckt:
quelle
Test.class.getResource("Test.class")
, die den Paketnamen nicht wiederholt.Test.class.getResource(Test.class.getSimpleName() + ".class")
BouncyCastleProvider
vollständigen Paketnamen ist jedoch erforderlich.getClassLoader()
, zurückzukehrennull
. Sehen Sie hier für eine Erweiterung dieser Methode zu behandeln , die.Eine andere Möglichkeit, herauszufinden, woher eine Klasse geladen wird (ohne die Quelle zu manipulieren), besteht darin, die Java-VM mit der folgenden Option zu starten:
-verbose:class
quelle
quelle
Dies ist, was wir verwenden:
Dies funktioniert abhängig von der ClassLoader-Implementierung:
getClass().getProtectionDomain().getCodeSource().getLocation()
quelle
Jons Version schlägt fehl, wenn das Objekt
ClassLoader
registriert ist,null
was darauf hindeutet, dass es vom Boot geladen wurdeClassLoader
.Diese Methode behandelt dieses Problem:
quelle
Bearbeiten Sie nur die erste Zeile:
Main
.classAusgabe:
Vielleicht schlechter Stil, funktioniert aber gut!
quelle
Normalerweise verwenden wir keine Hardcodierung. Wir können zuerst className abrufen und dann ClassLoader verwenden, um die Klassen-URL abzurufen.
quelle
Schauen Sie sich diese ähnliche Frage an. Werkzeug, um die gleiche Klasse zu entdecken ..
Ich denke, das wichtigste Hindernis ist, wenn Sie einen benutzerdefinierten Klassenladeprogramm haben (Laden von einer Datenbank oder einer LDAP).
quelle
Einfacher Weg:
Unser Beispiel:
Oder
Unser Beispiel:
quelle
Dieser Ansatz funktioniert sowohl für Dateien als auch für Gläser:
quelle
Angenommen, Sie arbeiten mit einer Klasse namens
MyClass
, sollte Folgendes funktionieren:Ob Sie den Speicherort der .class-Datei auf der Festplatte abrufen können oder nicht, hängt vom Klassenladeprogramm selbst ab. Wenn Sie beispielsweise BCEL verwenden, verfügt eine bestimmte Klasse möglicherweise nicht einmal über eine Darstellung auf der Festplatte.
quelle