En Class#getResourceAsStream()
kann einen Pfad annehmen, der relativ zum Ort der Class
die Sie dort als Ausgangspunkt verwenden. Wenn sich die Klasse also zum Beispiel im Verzeichnis com.example
Paket und Sie fordern den Pfad foo/filename.properties
dann wird es eigentlich Laden Sie die com/example/foo/filename.properties
Datei. Aber wenn Sie die /foo/filename.properties
dann wird es eigentlich laden foo/filename.properties
aus dem Klassenpfad Root.
Also, Ihr Code
java.util.Properties prop = new java.util.Properties();
String path = "localization/stat_codes.properties";
InputStream foo = prop.getClass().getResourceAsStream(path);
wird eigentlich suchen java/util/localization/stat_codes.properties
fichier.
Aber in Anwendungen mit einer komplexen Hierarchie von mehreren Classloadern ist der eine Classloader nicht der andere. Der Classloader, der die Kern-Java-Klassen geladen hat, hat nicht notwendigerweise Kenntnisse über die Dateien, die in der Webapp /WEB-INF/classes
. Daher wird der Pfad mit dem Präfix /
nicht zwangsläufig die Lösung sein wird, würde es immer noch null
.
Wenn Sie garantieren können, dass die aktuelle Klasse vom gleichen Classloader wie die Eigenschaftsdateien sichtbar ist (weil sie sich im gleichen Unterverzeichnis des Klassenpfads befinden, z. B. /WEB-INF/classes
verwenden, dann sollten Sie tatsächlich
String path = "/localization/stat_codes.properties";
InputStream foo = this.getClass().getResourceAsStream(path);
Wenn aber irgendwann die Eigenschaftsdateien wegen der einfacheren Wartung/Bearbeitung während der Laufzeit externalisiert werden, so dass Sie die Webapp nicht jedes Mal neu erstellen/verteilen/neustarten müssen, wenn Sie die Dateien bearbeiten wollen, dann wird die obige Codezeile wahrscheinlich ebenfalls fehlschlagen. Der ausgelagerte Speicherort wäre nur über einen anderen Classloader zugänglich. Die kanonische Lösung besteht darin, stattdessen den Kontext-Classloader des Threads als Startpunkt zu verwenden, der Zugriff hat auf tous Ressourcen im Klassenpfad.
String path = "localization/stat_codes.properties";
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream foo = loader.getResourceAsStream(path);
(Beachten Sie, dass dieser nicht einen Pfad nehmen kann, der mit /
Sie ist immer relativ zur gemeinsamen Wurzel)
Siehe auch: