Generating String from Exception-Stacktrace
April 5th, 2009
When it comes to Exceptions in Java there are lots of strategies how to deal (or not to deal) with them. But don’t be scared: I won’t blog about correct Exception-Chaining or stuff like that.
But did you ever think about converting an Exception including the complete stacktrace into a String and e.g. send that String by email?
As Java developer you might think: Hey, an Exception extends java.lang.Object and therefore must have a toString()-method, that returns a String. That’s absolutely correct! But the resulting String only gives you the type of the Exception, rather than the complete stacktrace.
If you want to include all the information that is printed on std.err when doing a exception.printStackTrace(), a little more effort has to be made.
The class in the listing below shows how to achieve that with the use a StringWriter and a Printwriter.
Below is a summary of the output of the three possibilities - exception.printStackTrace() prints to std.err, the other two to std.out.
exception.printStackTrace():
java.lang.NullPointerException
at ExceptionToString.main(ExceptionToString.java:16)
——–
exception.toString():
java.lang.NullPointerException
——–
getStringFromException(exception):
java.lang.NullPointerException
at ExceptionToString.main(ExceptionToString.java:16)
By the way: the first line of the stacktrace contains the toString()-result of the Exception.
Happy Coding,
Tino
But did you ever think about converting an Exception including the complete stacktrace into a String and e.g. send that String by email?
As Java developer you might think: Hey, an Exception extends java.lang.Object and therefore must have a toString()-method, that returns a String. That’s absolutely correct! But the resulting String only gives you the type of the Exception, rather than the complete stacktrace.
If you want to include all the information that is printed on std.err when doing a exception.printStackTrace(), a little more effort has to be made.
The class in the listing below shows how to achieve that with the use a StringWriter and a Printwriter.
| Java | | copy code | | ? |
| 001 | import java.io.Closeable; |
| 002 | import java.io.Flushable; |
| 003 | import java.io.IOException; |
| 004 | import java.io.PrintWriter; |
| 005 | import java.io.StringWriter; |
| 006 | |
| 007 | public class ExceptionToString { |
| 008 | |
| 009 | private final static String SEPARATOR = "\n -------- \n"; |
| 010 | |
| 011 | /** For testing purposes */ |
| 012 | @SuppressWarnings("null") |
| 013 | public static void main(String[] args) { |
| 014 | try { |
| 015 | |
| 016 | Integer i = null; |
| 017 | System.out.println(i.intValue()); |
| 018 | |
| 019 | } catch (NullPointerException exception) { |
| 020 | |
| 021 | System.out.println("exception.printStackTrace():"); |
| 022 | exception.printStackTrace(); |
| 023 | System.out.println(SEPARATOR); |
| 024 | |
| 025 | System.out.println("exception.toString():"); |
| 026 | System.out.println(exception.toString()); |
| 027 | System.out.println(SEPARATOR); |
| 028 | |
| 029 | System.out.println("getStringFromException(exception):"); |
| 030 | System.out.println(getStringFromException(exception)); |
| 031 | } |
| 032 | } |
| 033 | |
| 034 | /** |
| 035 | * Generates a String from the stacktrace of an Exception and returns that String |
| 036 | * |
| 037 | * @param exception |
| 038 | * |
| 039 | * @return the stacktrace of an Exception as String. |
| 040 | */ |
| 041 | protected static String getStringFromException(Exception exception) { |
| 042 | |
| 043 | if (exception == null) |
| 044 | return null; |
| 045 | |
| 046 | StringWriter stringWriter = null; |
| 047 | PrintWriter printWriter = null; |
| 048 | |
| 049 | try { |
| 050 | stringWriter = new StringWriter(); |
| 051 | printWriter = new PrintWriter(stringWriter); |
| 052 | |
| 053 | exception.printStackTrace(printWriter); |
| 054 | |
| 055 | return stringWriter.toString(); |
| 056 | |
| 057 | } finally { |
| 058 | flush(printWriter, stringWriter); |
| 059 | close(printWriter, stringWriter); |
| 060 | } |
| 061 | } |
| 062 | |
| 063 | /** |
| 064 | * Flushes any given Flushables |
| 065 | * |
| 066 | * @param flushables |
| 067 | */ |
| 068 | private static void flush(Flushable... flushables) { |
| 069 | |
| 070 | if (flushables == null) |
| 071 | return; |
| 072 | |
| 073 | for (Flushable flushable : flushables) { |
| 074 | if (flushable != null) |
| 075 | try { |
| 076 | flushable.flush(); |
| 077 | } catch (IOException exception) { |
| 078 | exception.printStackTrace(); |
| 079 | } |
| 080 | } |
| 081 | } |
| 082 | |
| 083 | /** |
| 084 | * Closes any given Closeables |
| 085 | * |
| 086 | * @param closeables |
| 087 | */ |
| 088 | private static void close(Closeable... closeables) { |
| 089 | |
| 090 | if (closeables == null) |
| 091 | return; |
| 092 | |
| 093 | for (Closeable closeable : closeables) { |
| 094 | if (closeable != null) |
| 095 | try { |
| 096 | closeable.close(); |
| 097 | } catch (IOException exception) { |
| 098 | exception.printStackTrace(); |
| 099 | } |
| 100 | } |
| 101 | } |
| 102 | } |
Below is a summary of the output of the three possibilities - exception.printStackTrace() prints to std.err, the other two to std.out.
exception.printStackTrace():
java.lang.NullPointerException
at ExceptionToString.main(ExceptionToString.java:16)
——–
exception.toString():
java.lang.NullPointerException
——–
getStringFromException(exception):
java.lang.NullPointerException
at ExceptionToString.main(ExceptionToString.java:16)
By the way: the first line of the stacktrace contains the toString()-result of the Exception.
Happy Coding,
Tino