# Exception Behandlung mit setDefaultUncaughtExceptionHandler, insbesondere im EventDispatcher Thread



## nicco80 (23. Apr 2010)

Hi,
zunächst mal ein dickes Lob an das gute Forum, ich habe schon oft Dinge hier gefunden die mir weiterhalfen. - Jetzt hab mich mir auch mal einen Account besorgt, und hier kommt auch schon das Problem;

Ich möchte einen ExceptionHandler implementieren, der in einer Swing-Applikation einen Dialog öffnet in der die Fehlermeldung beschrieben ist und im zweiten Schritt nach Benutzerbestätigung eine Nachricht an mich als Entwickler verschickt wird.
Dazu hab ich das hier gemacht:

```
Thread.setDefaultUncaughtExceptionHandler(exceptionReporter);
```
Und nach Recherche auch die laufenden Threads enumeriert, wie hier empfohlen: Listing All Running Threads | Example Depot
dort dann im Thread-Visitor per 

```
thread.setUncaughtExceptionHandler(exceptionReporter);
```
ebenfalls den Handler gesetzt.
Wenn ich nun eine Beispiel-Exception werfe (aus actionPerformed eines Buttons, also dem AWT-EventDispatcher), so wird der Handler leider _nicht_ aufgerufen.

Wenn ich durch den Thread-Visitor debugge so finde ich den AWT-EventDispatcher vor, nach dieser Doku zu urteilen müsste das doch funktionieren, oder ?
How uncaught exceptions are handled in Java

Möglicherweise muss man anders herangehen, hat jemand sowas schon mal implementiert gesehen?
Für Hinweise und Vorschläge bin ich dankbar, immer her damit 
grüsse nicco


----------



## Wildcard (23. Apr 2010)

nicco80 hat gesagt.:


> Und nach Recherche auch die laufenden Threads enumeriert, wie hier empfohlen: Listing All Running Threads | Example Depot
> dort dann im Thread-Visitor per
> 
> ```
> ...


Wann tust du das denn? Vermutlich war der EDT noch gar nicht gestartet und bekommt daher auch keinen UncaughtExceptionHandler zugewiesen. Sollte sich im Debugger leicht nachprüfen lassen...
Dir sollte auch klar sein das ein UncaughtExceptionHandler das Verhalten des Event Processings verändert. Wenn dir das egal ist, dann vergiss das ich es erwähnt habe...


----------



## nicco80 (23. Apr 2010)

Hi,


Wildcard hat gesagt.:


> Wann tust du das denn? Vermutlich war der EDT noch gar nicht gestartet und bekommt daher auch keinen UncaughtExceptionHandler zugewiesen. Sollte sich im Debugger leicht nachprüfen lassen...


Ja oft ist es aus der IDE schnell erkannt, ich habe trotzdem alles kurz zusammengefasst in der Datei "ExceptionTest.java", die Registrierung des Handlers klappt so wie unten vorgenommen nicht :autsch:

Ich habe sowas schonmal für die .net clr gemacht, weshalb ich vermute das ich etwas übersehen habe. So haben wir wenigstens ein Codeschnipsel zum dran rumschrauben.

Wie gesagt, was ich möglichst erreichen möchte, ist jede Exception abfangen um sie zu verarbeiten vielleicht bin ich da mit diesem Ansatz auf dem Holzweg - haben meine Recherchen so ergeben.. :bahnhof:
Danke, grüsse nicco


```
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

final class ExceptionReporting implements Thread.UncaughtExceptionHandler
{
	private ExceptionReporting() 
	{
	}
	
	private static ExceptionReporting exceptionReporter;
	
	/**
	 * Sets up a default handler for uncaught exceptions
	 * @param useGui
	 */
	public static synchronized void registerExceptionReporter()
	{
		if (exceptionReporter != null) {
			exceptionReporter = new ExceptionReporting();
		}

		Thread.setDefaultUncaughtExceptionHandler(exceptionReporter);

		ThreadGroup root = Thread.currentThread().getThreadGroup().getParent(); 
		while (root.getParent() != null) 
		{ 
			root = root.getParent(); 
		} 

		// Visit each thread group 
		visit(root, 0, exceptionReporter); 
	}

	// This method recursively visits all thread groups under `group'. 
	public static void visit(ThreadGroup group, int level, ExceptionReporting exceptionReporter) 
	{ 
		// Get threads in `group' 
		int numThreads = group.activeCount(); 
		Thread[] threads = new Thread[numThreads*2]; 
		numThreads = group.enumerate(threads, false); 
		
		// Enumerate each thread in `group' 
		for (int i=0; i<numThreads; i++) { // Get thread 
			Thread thread = threads[i]; 
			thread.setUncaughtExceptionHandler(exceptionReporter);
		} 
		
		// Get thread subgroups of `group' 
		int numGroups = group.activeGroupCount(); 
		ThreadGroup[] groups = new ThreadGroup[numGroups*2]; 
		numGroups = group.enumerate(groups, false); 
		
		// Recursively visit each subgroup 
		for (int i=0; i<numGroups; i++) { 
			visit(groups[i], level+1, exceptionReporter); 
		} 
	} 
	
	/**
	 * Catches exceptions and notifies the server service
	 */
	public void uncaughtException(Thread t, Throwable e) 
	{
		JOptionPane.showMessageDialog(
				null, e.getMessage(), 
				"Exception occurred",
				JOptionPane.ERROR_MESSAGE);
	}
	
}

public class ExceptionTest 
{
	public static void main(String[] args)
	{
		//too early: ExceptionReporting.registerExceptionReporter();
		
		new ExceptionTest();
	}
	
	public ExceptionTest()
	{
		JFrame jFrame = new JFrame();
		jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		//too early either: ExceptionReporting.registerExceptionReporter();
		
		SwingUtilities.invokeLater(new Runnable() {
			public void run()
			{ //does not work as well:
				ExceptionReporting.registerExceptionReporter();
			}
		});
		
		JButton button = new JButton("Create Exception from EDT");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e)
			{
				throw new RuntimeException("Test Exception");
				//throw new OutOfMemoryError("Test Exception");
			}
		});
		
		jFrame.getContentPane().add(button);
		jFrame.setVisible(true);
	}
}
```


----------



## nicco80 (24. Apr 2010)

Ich hab eine Erklärung und Lösung gefunden - 
Catching uncaught exceptions – Magpiebrain
beschreibt wie man die Event-Queue des default toolkits nutzt um die Exceptions abzufangen.
Das werd ich mir jetzt mal ansehen, denke das es damit geht und weil ich heute ebenso gut gelaunt bin, der kollege hier: :lol:


----------



## nicco80 (24. Apr 2010)

Ähm Nachtrag, mir ist da ein Fehler unterlaufen...

[JAVA=22]
		if (exceptionReporter == null) {
			exceptionReporter = new ExceptionReporting();
		}
[/code]



Kein Wunder dass es nicht funktionierte das passiert manchmal


----------

