EN · DE · RU · FR · ES

#300: ProjectForgeApplication.java

projectforge-application/src/main/java/org/projectforge/start/ProjectForgeApplication.java · Punto de entrada de Spring Boot · 194 líneas · 128 código · 49 comentarios · 17 en blanco
El punto de entrada único para todo el servidor ProjectForge. Ejecutar con ./gradlew bootRun o java -jar projectforge-application.jar. Anotado con @SpringBootApplication (habilita la auto-configuración, el escaneo de componentes y la auto-configuración) y @ServletComponentScan (descubre anotaciones @WebFilter/@WebServlet para servlets Wicket y REST). Extiende SpringBootServletInitializer para soporte de despliegue WAR tradicional.

Secuencia de inicio

1. Análisis de argumentos: Los argumentos personalizados se extraen antes de que Spring Boot los procese. --base-dir=/ruta establece el directorio de trabajo (logs, configuración, archivos temporales). --time-zone=Europe/Berlin establece TimeZone.setDefault(). Los argumentos desconocidos se pasan a Spring Boot para su manejo estándar (puerto, perfiles, etc.).

2. Resolución del directorio base (orden de prioridad):
① Argumento CLI --base-dir → ② propiedad del sistema projectforge.base-dir → ③ variable de entorno PROJECTFORGE_BASE_DIR → ④ ~/.projectforge (predeterminado)

3. Inicialización de directorios: Crea los subdirectorios logs/, temp/ y fonts/ bajo el directorio base. Escribe el PID del proceso actual en temp/projectforge.pid para monitoreo y scripts de apagado.

4. Configuración de zona horaria: Establece TimeZone.setDefault() al valor configurado (predeterminado: UTC). Esto es crítico — todos los cálculos de fecha del lado del servidor usan esta zona horaria. El frontend puede mostrar fechas en la zona horaria local del usuario, pero el servidor opera en una zona única y consistente.

5. Banner de versión: Lee META-INF/projectforge-version.properties (generado por Gradle) y registra la versión, la marca de tiempo de compilación y el hash del commit de git.

6. Inicio de Spring Boot: Llama a SpringApplication.run() con el contexto de la aplicación completamente configurado.

Manejo de errores al inicio

Conflicto de puerto: Captura ConnectorStartFailedException — si el puerto 8080 ya está en uso, lee el PID existente de temp/projectforge.pid y registra un mensaje claro: "El puerto 8080 ya está en uso por el proceso PID=XXXXX". NO reintenta ni cambia automáticamente de puerto — el administrador debe resolver el conflicto manualmente.

Apagado seguro: Registra un hook de apagado mediante SecurityShutdown que limpia datos sensibles (contraseñas, tokens, claves de cifrado) de la memoria al finalizar la JVM. Esta es una medida de defensa en profundidad — si el heap de la JVM se vuelca después del apagado, los datos sensibles deberían estar puestos a cero.

Jerarquía de clases

ProjectForgeApplication extends SpringBootServletInitializer — esto permite el despliegue como un archivo WAR tradicional en un contenedor de servlets (Tomcat, Jetty) además del modo de servidor embebido. El método configure() se sobrescribe para establecer las fuentes en ProjectForgeApplication.class, indicando al contenedor de servlets qué clase de configuración de Spring debe arrancar.

La anotación @ServletComponentScan es esencial para la compatibilidad con Wicket — Wicket registra su filtro mediante la anotación @WebFilter en lugar de FilterRegistrationBean de Spring Boot, y sin @ServletComponentScan el filtro de Wicket nunca sería descubierto.

Historial de Git

CommitQué cambió
868d6abb7Copyright 2025→2026
63081666fCopyright 2024→2025
b6092df09Copyright 2023→2024
ab45d51faCopyright 2001-2022→2001-2023
5f7ef41b8Copyright 2021→2022
ceb63e8a1Copyright 2001-2021
7c79f192Copyright 2020
dd5ca38acCommit inicial — ProjectForgeApplication creado como punto de entrada de Spring Boot con análisis de argumentos, configuración de directorios y configuración de zona horaria.
9ebb88522Creación del proyecto — este archivo formaba parte de la estructura inicial del proyecto.
¿Por qué dos modos de inicio? La clase soporta tanto java -jar (Tomcat embebido mediante Spring Boot) como despliegue WAR (Tomcat externo mediante SpringBootServletInitializer). El modo WAR es utilizado por organizaciones que tienen infraestructura Tomcat existente y prefieren desplegar ProjectForge junto con otras aplicaciones web. El modo JAR es más simple para desarrollo y despliegues en Docker.