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)