EN · DE · RU · FR · ES

#300: ProjectForgeApplication.java

projectforge-application/src/main/java/org/projectforge/start/ProjectForgeApplication.java · Spring Boot Einstiegspunkt · 194 Zeilen · 128 Code · 49 Kommentare · 17 Leerzeilen
Der einzige Einstiegspunkt für den gesamten ProjectForge-Server. Start mit ./gradlew bootRun oder java -jar projectforge-application.jar. Annotiert mit @SpringBootApplication (aktiviert Auto-Konfiguration, Komponenten-Scanning und Auto-Konfiguration) und @ServletComponentScan (erkennt @WebFilter/@WebServlet-Annotationen für Wicket- und REST-Servlets). Erweitert SpringBootServletInitializer für die Unterstützung traditioneller WAR-Bereitstellung.

Startsequenz

1. Argument-Parsing: Benutzerdefinierte Argumente werden extrahiert, bevor Spring Boot sie verarbeitet. --base-dir=/pfad setzt das Arbeitsverzeichnis (Logs, Konfiguration, temporäre Dateien). --time-zone=Europe/Berlin setzt TimeZone.setDefault(). Unbekannte Argumente werden an Spring Boot zur Standardbehandlung (Port, Profile usw.) weitergeleitet.

2. Basisverzeichnis-Auflösung (Prioritätsreihenfolge):
--base-dir CLI-Argument → ② Systemeigenschaft projectforge.base-dir → ③ Umgebungsvariable PROJECTFORGE_BASE_DIR → ④ ~/.projectforge (Standard)

3. Verzeichnisinitialisierung: Erstellt die Unterverzeichnisse logs/, temp/ und fonts/ unter dem Basisverzeichnis. Schreibt die aktuelle Prozess-PID in temp/projectforge.pid für Überwachungs- und Herunterfahrskripte.

4. Zeitzonen-Einrichtung: Setzt TimeZone.setDefault() auf den konfigurierten Wert (Standard: UTC). Dies ist kritisch – alle serverseitigen Datumsberechnungen verwenden diese Zeitzone. Das Frontend kann Daten in der lokalen Zeitzone des Benutzers anzeigen, aber der Server arbeitet in einer einzigen konsistenten Zone.

5. Versionsbanner: Liest META-INF/projectforge-version.properties (von Gradle generiert) und protokolliert die Version, den Build-Zeitstempel und den Git-Commit-Hash.

6. Spring Boot Start: Ruft SpringApplication.run() mit dem vollständig konfigurierten Anwendungskontext auf.

Fehlerbehandlung beim Start

Portkonflikt: Fängt ConnectorStartFailedException – wenn Port 8080 bereits belegt ist, wird die vorhandene PID aus temp/projectforge.pid gelesen und eine klare Meldung protokolliert: "Port 8080 wird bereits von Prozess PID=XXXXX verwendet". Es wird NICHT wiederholt oder automatisch umgeschaltet – der Administrator muss den Konflikt manuell lösen.

Graceful Shutdown: Registriert einen Shutdown-Hook über SecurityShutdown, der sensible Daten (Passwörter, Token, Verschlüsselungsschlüssel) bei JVM-Beendigung aus dem Speicher löscht. Dies ist eine Maßnahme zur Verteidigung in der Tiefe – falls der JVM-Heap nach dem Herunterfahren ausgelesen wird, sollten sensible Daten genullt sein.

Klassenhierarchie

ProjectForgeApplication extends SpringBootServletInitializer – dies ermöglicht die Bereitstellung als traditionelle WAR-Datei in einem Servlet-Container (Tomcat, Jetty) zusätzlich zum eingebetteten Server-Modus. Die Methode configure() wird überschrieben, um die Quellen auf ProjectForgeApplication.class zu setzen und dem Servlet-Container mitzuteilen, welche Spring-Konfigurationsklasse gebootstrapt werden soll.

Die Annotation @ServletComponentScan ist für die Wicket-Kompatibilität unerlässlich – Wicket registriert seinen Filter über die @WebFilter-Annotation anstelle von Spring Boots FilterRegistrationBean, und ohne @ServletComponentScan würde der Wicket-Filter nie gefunden werden.

Git-Verlauf

CommitWas wurde geändert
868d6abb7Copyright 2025→2026
63081666fCopyright 2024→2025
b6092df09Copyright 2023→2024
ab45d51faCopyright 2001-2022→2001-2023
5f7ef41b8Copyright 2021→2022
ceb63e8a1Copyright 2001-2021
7c79f192Copyright 2020
dd5ca38acErster Commit – ProjectForgeApplication als Spring Boot Einstiegspunkt mit Argument-Parsing, Verzeichniseinrichtung und Zeitzonenkonfiguration erstellt.
9ebb88522Projekterstellung – diese Datei war Teil der anfänglichen Projektstruktur.
Warum zwei Startmodi? Die Klasse unterstützt sowohl java -jar (eingebetteter Tomcat über Spring Boot) als auch WAR-Bereitstellung (externer Tomcat über SpringBootServletInitializer). Der WAR-Modus wird von Organisationen verwendet, die eine vorhandene Tomcat-Infrastruktur haben und ProjectForge lieber neben anderen Webanwendungen bereitstellen. Der JAR-Modus ist einfacher für Entwicklung und Docker-Bereitstellungen.