Ausgeben eines StackTrace in Java

15.08.2012

StackTrace ausgeben

Hier wird ganz kurz beschrieben, wie einfach es ist, einen StackTrace einer Exception in Java in einen String zu schreiben oder auf der Konsole mit System.out.println auszugeben.

Ich habe schon eine Reihe interessante Möglichkeiten gesehen, wie Leute versuchen, einen StackTrace auseinanderzunehmen, um ihn dann wieder mit einem StringBuilder oder StringBuffer zusammenzusetzen. Und das alles, um ihn danach auf der Konsole auszugeben oder in einen Dialog anzuzeigen.

Allerdings ist das meistens völlig überflüssig. Der folgende Code-Schnipsel zeigt eine einfache Möglichkeit, wie man es richtig macht. Als erstes wird eine NullPointerException provoziert und im catch-Block gefangen. Dadurch, dass die Klasse Exception, die Methode public void printStackTrace(PrintStream s) anbietet, kann ein ByteArrayOutputStream verwendet werden, um den StackTrace dort hinein schreiben zu lassen. Der ByteArrayOutputStream lässt sich anschließend einfach ausgeben.

try {
   String t = null;
   t.trim();
} catch(Exception e) {
   final ByteArrayOutputStream stream = new ByteArrayOutputStream();
   e.printStackTrace(new PrintStream(stream));
   System.out.println(stream);
}

Es ist zu beachten, dass die Methode toString() von stream automatisch aufgerufen wird, d.h. wenn man den StackTrace in einer Variable String speichern möchte, dann muss stream.toString() aufgerufen werden.

String stackTrace = "No StackTrace";
try {
   String t = null;
   t.trim();
} catch(Exception e) {
   final ByteArrayOutputStream stream = new ByteArrayOutputStream();
   e.printStackTrace(new PrintStream(stream));
   stackTrace = stream.toString();
}

Anzumerken ist, dass die Klasse Exception die Funktion getStrackTrace() anbietet, die als Rückgabewert ein Array von StackTraceElement-Elementen hat. Diese Methode sollte nur verwendet werden, wenn man vorhat einzelne Zeile des StackTrace in irgendeiner Form zu verändern. Beispielsweise eine HTML-Darstellung zu erzeugen, bei der die zweite Zeile vervorgehoben ist: (Die Funktionen f1, f2, f3 wurden nur eingefügt, damit der StackTrace mehrere Zeilen hat.)

public static void main(String[] args) {
	
	try {
		f1();
	} catch (Exception e) {
		StringBuilder sb = new StringBuilder();
		sb = sb.append("<code><strong>Exception type:</strong>");
		sb = sb.append(e.toString());
		sb = sb.append("<br>");
		StackTraceElement[] ste = e.getStackTrace();
		for(int i=0;i<ste.length;i++) {
			if(i==1) {
				sb = sb.append("<strong>");
			}
			sb = sb.append("<em>");
			sb = sb.append(ste[i]);
			sb = sb.append("</em> <br>");
			if(i==1) {
				sb = sb.append("</strong>");
			}
		}
		sb = sb.append("</code>");
		System.out.println(sb.toString());
	}
}


public static void f1() {
	f2();
}

public static void f2() {
	f3();
}

public static void f3() {
	String n = null;
	n.trim();
}	

Das Ergebnis zu dem Beispiel sieht dann so aus:

Exception type:java.lang.NullPointerException
StackTraceTest.f3(StackTraceTest.java:44)
StackTraceTest.f2(StackTraceTest.java:39)
StackTraceTest.f1(StackTraceTest.java:35)
StackTraceTest.main(StackTraceTest.java:10)