Apa adalah cara termudah untuk mengkonversi hasil dari Throwable.getStackTrace()
untuk string yang menggambarkan jejak stack?
Gunakan Throwable.printStackTrace(PrintWriter pw)
untuk mengirim stack trace yang sesuai penulis.
import java.io.StringWriter;
import java.io.PrintWriter;
// ...
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); // stack trace as a string
System.out.println(sStackTrace);
Satu dapat menggunakan metode berikut untuk mengkonversi Pengecualian
stack trace String
. Kelas ini tersedia di Apache commons-lang yang paling umum tergantung perpustakaan dengan banyak terbuka populer sumber
org.apache.commons.lang.terkecuali.ExceptionUtils.getStackTrace(Throwable)
Jika anda sedang mengembangkan untuk Android, cara yang jauh lebih mudah adalah dengan menggunakan ini:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
Format ini sama seperti getStacktrace, misalnya
09-24 16:09:07.042: I/Sistem.keluar(4844): jawa.lang.NullPointerException 09-24 16:09:07.042: I/Sistem.keluar(4844): di com.temp.ttscancel.MainActivity.onCreate(MainActivity.jawa:43) 09-24 16:09:07.042: I/Sistem.keluar(4844): di android.aplikasi.Kegiatan.performCreate(Aktivitas.jawa:5248) 09-24 16:09:07.043: I/Sistem.keluar(4844): di android.aplikasi.Instrumentasi.callActivityOnCreate(Instrumentasi.jawa:1110) 09-24 16:09:07.043: I/Sistem.keluar(4844): di android.aplikasi.ActivityThread.performLaunchActivity(ActivityThread.jawa:2162) 09-24 16:09:07.043: I/Sistem.keluar(4844): di android.aplikasi.ActivityThread.handleLaunchActivity(ActivityThread.jawa:2257) 09-24 16:09:07.043: I/Sistem.keluar(4844): di android.aplikasi.ActivityThread.akses$800(ActivityThread.jawa:139) 09-24 16:09:07.043: I/Sistem.keluar(4844): di android.aplikasi.ActivityThread$H. handleMessage(ActivityThread.jawa:1210) 09-24 16:09:07.043: I/Sistem.keluar(4844): di android.os.Handler.dispatchMessage(Handler.jawa:102) 09-24 16:09:07.043: I/Sistem.keluar(4844): di android.os.Looper.loop(Looper.jawa:136) 09-24 16:09:07.044: I/Sistem.keluar(4844): di android.aplikasi.ActivityThread.utama(ActivityThread.jawa:5097) 09-24 16:09:07.044: I/Sistem.keluar(4844): di jawa.lang.mencerminkan.Metode.invokeNative(Native Method) 09-24 16:09:07.044: I/Sistem.keluar(4844): di jawa.lang.mencerminkan.Metode.invoke(Metode.jawa:515) 09-24 16:09:07.044: I/Sistem.keluar(4844): di com.android.internal.os.ZygoteInit$MethodAndArgsCaller.menjalankan(ZygoteInit.jawa:785) 09-24 16:09:07.044: I/Sistem.keluar(4844): di com.android.internal.os.ZygoteInit.utama(ZygoteInit.jawa:601)
Throwables
kelasJika anda memiliki yang sebenarnya Throwable
misalnya, Google Jambu menyediakan Throwables.getStackTraceAsString()
.
Contoh:
String s = Throwables.getStackTraceAsString ( myException ) ;
PERINGATAN: tidak termasuk penyebab (yang biasanya berguna sedikit!)
public String stackTraceToString(Throwable e) {
StringBuilder sb = new StringBuilder();
for (StackTraceElement element : e.getStackTrace()) {
sb.append(element.toString());
sb.append("\n");
}
return sb.toString();
}
public static String getStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
Berikut kode yang memungkinkan anda untuk mendapatkan seluruh jejak stack dengan String
format, tanpa menggunakan Api seperti log4J atau bahkan jawa.util.Logger
:
catch (Exception e) {
StackTraceElement[] stack = e.getStackTrace();
String exception = "";
for (StackTraceElement s : stack) {
exception = exception + s.toString() + "\n\t\t";
}
System.out.println(exception);
// then you can send the exception string to a external file.
}
Di sini adalah versi yang copy-pastable langsung ke code:
import java.io.StringWriter;
import java.io.PrintWriter;
//Two lines of code to get the exception into a StringWriter
StringWriter sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));
//And to actually print it
logger.info("Current stack trace is:\n" + sw.toString());
Atau, dalam menangkap blok
} catch (Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
logger.info("Current stack trace is:\n" + sw.toString());
}
Arrays.toString(thrown.getStackTrace())
Adalah cara termudah untuk mengkonversi hasil ke dalam String Saya menggunakan ini di program saya untuk mencetak stack trace
LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});
Mencetak stack trace ke PrintStream
, kemudian mengubahnya menjadi String
:
// ...
catch (Exception e)
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(out));
String str = new String(out.toByteArray());
System.out.println(str);
}
Percetakan stack trace ke string
import java.io.PrintWriter;
import java.io.StringWriter;
public class StackTraceUtils {
public static String stackTraceToString(StackTraceElement[] stackTrace) {
StringWriter sw = new StringWriter();
printStackTrace(stackTrace, new PrintWriter(sw));
return sw.toString();
}
public static void printStackTrace(StackTraceElement[] stackTrace, PrintWriter pw) {
for(StackTraceElement stackTraceEl : stackTrace) {
pw.println(stackTraceEl);
}
}
}
It's berguna ketika anda ingin mencetak thread saat ini jejak stack tanpa membuat instance dari Throwable
- tetapi perhatikan bahwa menciptakan baru Throwable
dan mendapatkan jejak stack dari ada benar-benar lebih cepat dan lebih murah daripada menelepon Benang.getStackTrace
.
Memperluas kelas Throwable akan memberikan String property kesalahan.stackTraceString
:
val Throwable.stackTraceString: String
get() {
val sw = StringWriter()
val pw = PrintWriter(sw)
this.printStackTrace(pw)
return sw.toString()
}
Pintar sniping di set pertama dari komentar itu sangat lucu, tapi itu benar-benar tergantung pada apa yang anda coba lakukan. Jika anda don't sudah memiliki perpustakaan benar, maka 3 baris kode (seperti di D. Wroblewski's jawaban) adalah sempurna. OTOH, jika anda sudah memiliki apache.commons perpustakaan (karena sebagian besar proyek-proyek besar akan), maka Amar's jawaban yang lebih pendek. OK, mungkin butuh sepuluh menit untuk sampai ke perpustakaan dan menginstalnya dengan benar (kurang dari satu jika anda tahu apa yang anda're doing). Tapi jam terus berdetak, jadi anda mungkin tidak memiliki waktu luang. Jarek Przygódzki memiliki peringatan yang menarik--"Jika anda don't perlu bersarang pengecualian".
Tapi bagaimana jika aku tidak membutuhkan penuh tumpukan jejak, bersarang dan semua? Dalam kasus itu, rahasianya adalah dengan menggunakan apache.umum's getFullStackTrace (lihat http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29)
Ia menyelamatkan aku. Terima kasih, Amar, untuk petunjuk!
Kode dari Apache Commons Lang 3.4 (Awal):
public static String getStackTrace(final Throwable throwable) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
Perbedaan dengan jawaban yang lain adalah bahwa menggunakan autoFlush
pada PrintWriter
.
Tanpa jawa.io.*
hal ini dapat dilakukan seperti ini.
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
Dan kemudian jejak
variabel memegang stack trace. Output juga memegang penyebab awal, output identik dengan printStackTrace()
Contoh, printStackTrace()
hasil:
java.io.FileNotFoundException: / (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at Test.main(Test.java:9)
The jejak
String memegang, ketika dicetak untuk stdout
java.io.FileNotFoundException: / (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at Test.main(Test.java:9)
jika anda menggunakan Java 8, coba ini
Arrays.stream(e.getStackTrace())
.map(s->s.toString())
.collect(Collectors.joining("\n"));
anda dapat menemukan kode untuk getStackTrace()
fungsi yang disediakan oleh Throwable.java
sebagai :
public StackTraceElement[] getStackTrace() {
return getOurStackTrace().clone();
}
dan untuk StackTraceElement
, itu penyedia toString()` sebagai:
public String toString() {
return getClassName() + "." + methodName +
(isNativeMethod() ? "(Native Method)" :
(fileName != null && lineNumber >= 0 ?
"(" + fileName + ":" + lineNumber + ")" :
(fileName != null ? "("+fileName+")" : "(Unknown Source)")));
}
Jadi hanya bergabung dengan StackTraceElement
dengan "\n".
sebuah exapansion pada Gala's jawaban yang juga akan mencakup penyebab pengecualian:
private String extrapolateStackTrace(Exception ex) {
Throwable e = ex;
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
while (e.getCause() != null) {
e = e.getCause();
trace += "Cause by: " + e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
}
return trace;
}