Where am I? Or how not to get lost in the file system of a Java application
\n\nEvery Java developer has asked themselves at least once: "Where, exactly, is my code running?" You start the program from the IDE, and everything works. But as soon as you move it to a server or a Docker container, the files that were supposed to be next to the jar file end up somewhere in the depths of /opt/app or /tmp. Sound familiar?
The question "How to get the current working directory in Java?" is one of the most popular on Stack Overflow. And for good reason: the answer seems obvious, but in practice it hides many pitfalls. In this article, we'll break down the best practices for 2025: how to reliably get the current working directory, when you can trust it, and when it's better to look for alternatives.
\n\nDisclaimer: The article is written for Java 17+ (LTS), but the examples are compatible with Java 11 and newer. If you're still on Java 8 — update urgently, but the code will still work.\n\n
The Classic Way: System.getProperty("user.dir")
\n\nThe simplest and most widely used method is to access the system property user.dir. This is what you'll see in 90% of Stack Overflow answers:
public class WorkingDirectoryExample {\n public static void main(String[] args) {\n String cwd = System.getProperty("user.dir");\n System.out.println("Current directory: " + cwd);\n }\n}\n\nWhat will you get as output? The path to the folder from which the JVM was launched. If you launch from the project root, it will be /Users/you/projects/my-app. If from target/, it will be target/.
Why is this not always reliable?
\n\nProblem #1: IDEs and build systems deceive you. IntelliJ IDEA by default sets the working directory to the module root. Maven — to the project root. Gradle — to the module root. But this can be overridden in the run configuration. As a result, the code works locally but not on the server.
\n\nProblem #2: Unit tests. When run via JUnit or TestNG, the working directory might be the project root, or it might be the build folder. It depends on the runner settings.
\n\nProblem #3: Web applications and microservices. In containers (Tomcat, Jetty), the working directory is often $CATALINA_HOME/bin or /. This has nothing to do with your WAR file.
The Modern Approach: java.nio.file.Paths
\n\nStarting with Java 7, we have a more "Java-like" way — via the 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("Current directory (NIO): " + cwd);\n }\n}\n\nWhat's happening here? Paths.get("") creates a reference to an empty path, which is interpreted as a relative path to the current directory. The toAbsolutePath() method resolves it to an absolute one. The result is the same user.dir, but with stronger typing.
Pros:
\n- \n
- Works with
Pathobjects, not strings (fewer errors with separators) \n - Can be used directly in modern APIs \n
- Cross-platform (Windows vs Linux) \n
Cons: all the same — it's still the process working directory.
\n\nAlternative: File("")
\n\nFor those who don't want to switch to NIO (though you should):
\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("Current directory (File): " + cwd);\n }\n}\n\nExactly the same as Paths.get("").toAbsolutePa