Wo bin ich? Oder wie man sich im Dateisystem einer Java-Anwendung nicht verirrt
\n\nJeder Java-Entwickler hat sich mindestens einmal im Leben gefragt: „Wo genau wird mein Code eigentlich ausgeführt?“ Man startet das Programm aus der IDE, alles funktioniert. Aber sobald man es auf einen Server oder in einen Docker-Container verschiebt, befinden sich die Dateien, die neben der JAR-Datei liegen sollten, plötzlich irgendwo in den Tiefen von /opt/app oder /tmp. Kommt Ihnen das bekannt vor?
Die Frage „How to get the current working directory in Java?“ ist eine der beliebtesten auf Stack Overflow. Und das zu Recht: Die Antwort scheint offensichtlich, birgt aber in der Praxis viele Fallstricke. In diesem Artikel behandeln wir die Best Practices für 2025: Wie man das aktuelle Arbeitsverzeichnis (current working directory) zuverlässig ermittelt, wann man ihm vertrauen kann und wann man besser nach Alternativen sucht.
\n\nHaftungsausschluss: Der Artikel wurde für Java 17+ (LTS) geschrieben, aber die Beispiele sind mit Java 11 und neuer kompatibel. Wenn Sie immer noch Java 8 verwenden – aktualisieren Sie dringend, aber der Code wird trotzdem funktionieren.\n\n
Der klassische Weg: System.getProperty("user.dir")
\n\nDie einfachste und am weitesten verbreitete Methode ist der Zugriff auf die Systemeigenschaft user.dir. Das sehen Sie in 90% der Antworten auf Stack Overflow:
public class WorkingDirectoryExample {\n public static void main(String[] args) {\n String cwd = System.getProperty("user.dir");\n System.out.println("Aktuelles Verzeichnis: " + cwd);\n }\n}\n\nWas erhalten Sie als Ausgabe? Den Pfad zu dem Ordner, aus dem die JVM gestartet wurde. Wenn Sie aus dem Projektstammverzeichnis starten, ist dies /Users/you/projects/my-app. Wenn Sie aus target/ starten, ist es target/.
Warum ist das nicht immer zuverlässig?
\n\nProblem Nr. 1: IDEs und Build-Systeme täuschen. IntelliJ IDEA setzt das Arbeitsverzeichnis standardmäßig auf das Modulstammverzeichnis. Maven auf das Projektstammverzeichnis. Gradle auf das Modulstammverzeichnis. Dies kann jedoch in der Startkonfiguration überschrieben werden. Infolgedessen funktioniert der Code lokal, aber auf dem Server nicht.
\n\nProblem Nr. 2: Unit-Tests. Bei der Ausführung über JUnit oder TestNG kann das Arbeitsverzeichnis das Projektstammverzeichnis oder der Build-Ordner sein. Dies hängt von den Einstellungen des Runners ab.
\n\nProblem Nr. 3: Webanwendungen und Microservices. In Containern (Tomcat, Jetty) ist das Arbeitsverzeichnis oft gleich $CATALINA_HOME/bin oder /. Dies hat nichts mit Ihrer WAR-Datei zu tun.
Der moderne Ansatz: java.nio.file.Paths
\n\nSeit Java 7 haben wir eine „java-typischere“ Methode – über die NIO.2-API:
\n\nimport java.nio.file.Paths;\n\npublic class NioWorkingDirectory {\n public static void main(String[] args) {\n String cwd = Paths.get("").toAbsolutePath().toString();\n System.out.println("Aktuelles Verzeichnis (NIO): " + cwd);\n }\n}\n\nWas passiert hier? Paths.get("") erstellt einen Verweis auf einen leeren Pfad, der als relativer Pfad zum aktuellen Verzeichnis interpretiert wird. Die Methode toAbsolutePath() löst ihn in einen absoluten Pfad auf. Das Ergebnis ist dasselbe wie user.dir, jedoch mit strengerer Typisierung.
Vorteile:
\n- \n
- Arbeitet mit
Path-Objekten, nicht mit Zeichenketten (weniger Fehler mit Trennzeichen) \n - Kann sofort in modernen APIs verwendet werden \n
- Plattformunabhängigkeit (Windows vs. Linux) \n
Nachteile: Dieselben – es ist immer noch das Arbeitsverzeichnis des Prozesses.
\n\nAlternative: File("")
\n\nFür diejenigen, die nicht auf NIO umsteigen möchten (obwohl das schade ist):
\n\nimport java.io.File;\n\npublic class FileWorkingDirectory {\n public static void main(String[] args) {\n String cwd = new File("").getAbsolutePath();\n System.out.println("Aktuelles Verzeichnis (File): " + cwd);\n }\n}\n\nAbsolut dasselbe wie Paths.get("").toAbsolutePa