¿Dónde estoy? O cómo no perderse en el sistema de archivos de una aplicación Java
\n\nTodo desarrollador Java al menos una vez en la vida se ha preguntado: «¿Y dónde, exactamente, se ejecuta mi código?» Parece que ejecutas el programa desde el IDE y todo funciona. Pero basta con moverlo a un servidor o a un contenedor Docker — y los archivos que deberían estar junto al archivo jar, terminan en algún lugar en las profundidades de /opt/app o /tmp. ¿Te suena familiar?
La pregunta «How to get the current working directory in Java?» es una de las más populares en Stack Overflow. Y no es casualidad: la respuesta parece obvia, pero en la práctica esconde muchas trampas. En este artículo analizaremos las mejores prácticas de 2025: cómo obtener de forma fiable el current working directory, cuándo se puede confiar en él y cuándo es mejor buscar alternativas.
\n\nDescargo de responsabilidad: el artículo está escrito para Java 17+ (LTS), pero los ejemplos son compatibles con Java 11 y versiones posteriores. Si todavía usas Java 8 — actualízate urgentemente, pero el código también funcionará.\n\n
La forma clásica: System.getProperty("user.dir")
\n\nEl método más simple y más utilizado es acceder a la propiedad del sistema user.dir. Esto es lo que verás en el 90% de las respuestas en Stack Overflow:
public class WorkingDirectoryExample {\n public static void main(String[] args) {\n String cwd = System.getProperty("user.dir");\n System.out.println("Directorio actual: " + cwd);\n }\n}\n\n¿Qué obtendrás como resultado? La ruta a la carpeta desde la cual se inició la JVM. Si ejecutas desde la raíz del proyecto, será /Users/you/projects/my-app. Si ejecutas desde target/, será target/.
¿Por qué no siempre es fiable?
\n\nProblema n.º 1: Los IDE y los sistemas de compilación engañan. IntelliJ IDEA por defecto establece el working directory igual a la raíz del módulo. Maven — la raíz del proyecto. Gradle — la raíz del módulo. Pero esto se puede sobrescribir en la configuración de ejecución. Como resultado, el código funciona en la máquina local, pero en el servidor no.
\n\nProblema n.º 2: Pruebas unitarias. Al ejecutar con JUnit o TestNG, el working directory puede ser la raíz del proyecto o la carpeta de compilación. Depende de la configuración del ejecutor de pruebas.
\n\nProblema n.º 3: Aplicaciones web y microservicios. En contenedores (Tomcat, Jetty), el working directory a menudo es $CATALINA_HOME/bin o /. No tiene ninguna relación con tu archivo WAR.
Enfoque moderno: java.nio.file.Paths
\n\nA partir de Java 7, tenemos una forma más «java» — a través de la API NIO.2:
\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("Directorio actual (NIO): " + cwd);\n }\n}\n\n¿Qué sucede aquí? Paths.get("") crea una referencia a una ruta vacía, que se interpreta como una ruta relativa al directorio actual. El método toAbsolutePath() la resuelve a una ruta absoluta. El resultado es el mismo user.dir, pero con un tipado más estricto.
Ventajas:
\n- \n
- Funciona con objetos
Path, no con cadenas (menos errores con separadores) \n - Se puede usar directamente en APIs modernas \n
- Multiplataforma (Windows vs Linux) \n
Desventajas: las mismas — sigue siendo el working directory del proceso.
\n\nAlternativa: File("")
\n\nPara aquellos que no quieren migrar a NIO (aunque es una lástima):
\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("Directorio actual (File): " + cwd);\n }\n}\n\nExactamente lo mismo que Paths.get("").toAbsolutePa