Java: Laufzeitausnahmen anzeigen – Variante
Im Artikel „Java: Laufzeitausnahmen anzeigen“ steht, wie ich im AWT-EventDispatchThread nicht gefangene Ausnahmen mit einem Dialog anzeige. Inzwischen verfolge ich eine weniger „aufdringliche“ Variante, die nicht von der Arbeit ablenkt oder das Schließen des Programmfensters verhindert, falls im EventDispatchThread
laufend neue Ausnahmen geworfen und nicht gefangen werden:
- Die Ersatz-
EventQueue
benutzt das Logging-System und loggt die Ausnahme mit dem LevelSEVERE
- Ein
Handler
– ein erweiterterjava.util.logging.Handler
– reagiert auf bestimmte Loglevel, zeigt beispielsweise einen „Fehlerindikator“ an, bei Klick darauf erhält der Benutzer nähere Informationen über den Fehler
Modifizierte EventQueue
public final class AppEventQueue extends java.awt.EventQueue { @Override protected void dispatchEvent(AWTEvent event) { try { super.dispatchEvent(event); } catch (Throwable t) { Logger.getLogger(AppEventQueue.class.getName()).log(Level.SEVERE, null, t); } } }
Handler
public final class ErrorLogHandler extends Handler { private static final int MIN_LOG_LEVEL_VALUE = Level.WARNING.intValue(); public ErrorLogHandler() { Logger.getLogger("").addHandler(this); } @Override public void publish(LogRecord record) { int recordLevelValue = record.getLevel().intValue(); boolean isError = recordLevelValue >= MIN_LOG_LEVEL_VALUE; if (isError) { // Hier den Fehler visualisieren } } @Override public void flush() { // ignorieren } @Override public void close() throws SecurityException { // ignorieren } }
Der Handler fügt sich dem root Logger hinzu, der root Logger ruft die Handler-Methode publish()
auf. Jeden Loglevel ab WARNING
betrachtet der Handler als Fehler (isError
). Bei Fehlern kann er beispielsweise über die setIcon()
-Methode eines Labels ein Fehler-Icon setzen und bei Klick auf das Label die Fehlerinformationen anzeigen, beispielsweise anhand Fehler-LogRecord
s, die er temporär speichert.
EventQueue ersetzen
Die EventQueue
ersetze ich „rechtzeitig“ durch folgende Codezeile (im Projekt JPhotoTagger unmittelbar nach Erzeugen des Programmfenster-Frames):
Toolkit.getDefaultToolkit().getSystemEventQueue().push(new AppEventQueue());
Die folgenden Abbildungen zeigen die Auswirkungen: In NetBeans setzte ich einen Haltepunkt in die Zeile 127 der Klasse AppInit
, Methode setJptEventQueue()
, das ist die Zeile mit dem push()
-Afuruf. Gelb unterlegt ist der Thread AWT-EventQueue-0. Nach Aufruf ist zu sehen, dass nun Thread AWT-EventQueue-1 läuft, die Namen lassen sich nicht ändern, es wird nur die Nummer hochgezählt.
JPhotoTagger: AWT-EventQueue ersetzen, Debugger-Ansicht vor Ersetzen
JPhotoTagger: AWT-EventQueue ersetzen, Debugger-Ansicht nach Ersetzen.
Fehleranzeige durch einen Log-Handler in JPhotoTagger am unteren Programmfensterrand.
Außerhalb der AWT-EventQueue
In anderen Threads kann ich nicht gefangene Ausnahmen loggen mit java.lang.Thread#setDefaultUncaughtExceptionHandler()
– der Handler wird nicht aufgerufen im AWT-Event Dispatch Thread. Beispiel:
public final class UncaughtExceptionLogger implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread t, Throwable e) { Logger.getLogger(UncaughtExceptionLogger.class.getName()).log(Level.SEVERE, null, e); } }
Benutzung:
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionLogger());
Zusammenfassung (mit Erweiterung um FileHandler)
- Nicht gefangene Ausnahmen sollen dem Benutzer unaufdringlich angezeigt werden und in einer Logdatei stehen
- Ein erweiterter
java.util.logging.Handler
zeigt dem Benutzer Probleme an ab dem LoglevelWARNING
, einjava.util.logging.FileHandler
schreibt die LogRecords in eine Logdatei. Diese Handler füge ich dem root Logger hinzu. - Je ein Logger loggt ungefangene Ausnahmen mit dem Level
SEVERE
- im AWT-EventDispatchThread in einer eigenen
EventQueue
, die die „Standard“-EventQueue
ersetzt - in (allen) anderen Threads in einem
java.lang.Thread.UncaughtExceptionHandler
, den ich setze mitThread#setDefaultUncaughtExceptionHandler()
- im AWT-EventDispatchThread in einer eigenen
Stichwörter: Exceptions, Java