#800: ExceptionHelper.java
projectforge-business/src/main/java/org/projectforge/framework/utils/ExceptionHelper.java · 97 Zeilen · 50 Code · 39 Kommentare · 8 Leerzeilen
Drei statische Hilfsmethoden für die Ausnahmebehandlung: Gefilterte Stacktraces (irrelevante Frames zusammenfalten und CGLIB-Proxys überspringen), Stacktrace in String (Standard-printStackTrace-in-Writer) und rekursive Ursachenermittlung. Hauptsächlich von der Sicherheits-/Zugriffsschicht verwendet, um lesbare Fehlermeldungen zu erzeugen, die nur ProjectForge-Codepfade zeigen, nicht Spring/Hibernate/Tomcat-Interna.
Methoden
| Methode | Funktion | Existenzgrund |
getFilteredStackTrace(ex, namespace) | Erstellt einen Stacktrace-String, der nur Frames aus dem angegebenen Namensraum enthält. Aufeinanderfolgende nicht passende Frames werden zu "at ..." zusammengefasst. Frames mit CGLIB$$ werden immer übersprungen – dies sind Hibernate-Proxy-Klassen mit verstümmelten Namen wie AddressDO$$EnhancerByCGLIB$$a1b2c3d4. | Zugriffsverletzungsfehler würden sonst 50+ Zeilen Spring Security- und Tomcat-Interna anzeigen, bevor die einzelne relevante ProjectForge-Zeile erscheint. Der gefilterte Trace zeigt nur die für den Entwickler relevante Aufrufkette. |
printStackTrace(ex) | Wandelt einen vollständigen Stacktrace über StringWriter+PrintWriter in einen String um. Standard-Java-Muster. | Logging-Frameworks benötigen String, nicht PrintStream. Wird verwendet, wenn Ausnahmen in JSON serialisiert oder in Datenbankspalten gespeichert werden müssen. |
getRootCause(ex) | Entpackt rekursiv getCause(), bis die innerste Ausnahme gefunden wird. Gibt die ursprüngliche Ausnahme zurück, wenn keine Ursache existiert. | Spring umschließt Ausnahmen stark (UndeclaredThrowableException, InvocationTargetException, DataAccessException). Der eigentliche Fehler liegt immer ganz unten. Diese Methode extrahiert ihn. |
Namensraum-Filteralgorithmus
Die Methode getFilteredStackTrace verwendet einen Zustandsautomaten-Ansatz mit zwei Modi:
Normalmodus: Frames ausgeben. Wenn ein nicht passender Frame auftritt, wird "at ..." ausgegeben (die irrelevanten Frames werden zusammengefasst) und in den Ignoriermodus gewechselt.
Ignoriermodus: Frames stillschweigend überspringen, bis ein passender Frame erscheint, dann zurück in den Normalmodus wechseln und diesen ausgeben.
Dies erzeugt kompakte Ausgaben wie: at org.projectforge.access.AccessChecker.check(AccessChecker.java:79) at ... at org.projectforge.task.TaskDao.hasAccess(TaskDao.java:176) – wobei "at ..." alle Spring/Tomcat/Hibernate-Frames zwischen den beiden relevanten Zeilen ersetzt.
Verwender
Wird von der Zugriffskontrollschicht (AccessCheckerImpl, AccessException) beim Erstellen von Fehlermeldungen für Berechtigungsverletzungen aufgerufen. Wird auch von ScriptExecutor verwendet, um lesbare Fehlerausgaben für fehlgeschlagene Groovy/Kotlin-Skripte zu erzeugen – ohne den gefilterten Trace würde eine einfache NPE in einem Skript einen 200-zeiligen Stacktrace erzeugen, der von Groovy-Laufzeit- und Spring-Proxy-Interna dominiert wird.
Git-Verlauf
| Commit | Änderungen |
868d6abb7 | Copyright 2025→2026 |
63081666f | Copyright 2024→2025 |
b6092df09 | Copyright 2023→2024 |
ab45d51fa | Copyright 2001-2022→2001-2023 |
5f7ef41b8 | Copyright 2021→2022 |
ceb63e8a1 | Copyright 2001-2021 |
7c79f192 | Copyright 2020 |
73a9755d | Code-Bereinigung für alle Utils. Identische Catch-Blöcke zusammengefasst, ArrayList<Class> durch Diamant-Operator ArrayList<> ersetzt, StringBuffer durch StringBuilder ersetzt, Collections.sort durch List.sort ersetzt. Der ExceptionHelper-Code selbst verwendet StringBuilder in getFilteredStackTrace – dieser Commit stellte die Konsistenz mit der projektsweiten Migration von synchronisiertem StringBuffer zu unsynchronisiertem StringBuilder sicher. |
Achtung – CGLIB$$-Erkennung: Die Methode ignore() prüft auf CGLIB$$ im Klassennamen. Wenn ProjectForge auf Hibernate 6.x aktualisiert, werden Proxys ByteBuddy anstelle von CGLIB verwenden – die Klassennamen enthalten dann $HibernateProxy$ oder $ByteBuddy$. Die Methode ignore() muss aktualisiert werden, um beide Muster zu verarbeiten.