Wie konvertiert man am einfachsten das Ergebnis von Throwable.getStackTrace()
zu einer Zeichenkette, die den Stacktrace darstellt?
Diese Lösung entfernt die Meldung und ignoriert alle übergeordneten Spuren
Wie konvertiert man am einfachsten das Ergebnis von Throwable.getStackTrace()
zu einer Zeichenkette, die den Stacktrace darstellt?
Code von Apache Commons Lang 3.4 ( JavaDoc ):
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();
}
Der Unterschied zu den anderen Antworten besteht darin, dass es verwendet autoFlush
über die PrintWriter
.
Mit Java 8 Stream-API können Sie etwa so vorgehen:
Stream
.of(throwable.getStackTrace())
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"));
Es nimmt ein Array von Stack-Trace-Elementen, konvertiert sie in einen String und fügt sie zu einem mehrzeiligen String zusammen.
Die cleveren Sticheleien in den ersten Kommentaren waren sehr amüsant, aber es kommt wirklich darauf an, was man zu tun versucht. Wenn Sie noch nicht über die richtige Bibliothek verfügen, dann sind 3 Zeilen Code (wie in der Antwort von D. Wroblewski) perfekt. Wenn Sie jedoch bereits die apache.commons-Bibliothek haben (was bei den meisten großen Projekten der Fall ist), ist die Antwort von Amar kürzer. OK, Sie brauchen vielleicht zehn Minuten, um die Bibliothek zu besorgen und sie korrekt zu installieren (weniger als eine, wenn Sie wissen, was Sie tun). Aber die Uhr tickt, also haben Sie vielleicht nicht die Zeit, die Sie erübrigen können. Jarek Przygódzki hatte einen interessanten Vorbehalt: "Wenn Sie keine verschachtelten Ausnahmen brauchen".
Aber was, wenn ich tun die vollständigen Stack Traces benötigen, verschachtelt und alles? In diesem Fall besteht das Geheimnis darin, die Funktion getFullStackTrace von apache.common zu verwenden (siehe http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29 )
Das hat mir den Hintern gerettet. Danke, Amar, für den Tipp!
Ohne java.io.*
kann es so gemacht werden.
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
Und dann die trace
enthält Ihre Stack-Trace-Variable. Die Ausgabe enthält auch die ursprüngliche Ursache, die Ausgabe ist identisch mit printStackTrace()
Beispiel, printStackTrace()
Erträge:
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)
Le site trace
String hält, wenn er nach 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)
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
8 Stimmen
Die Antwort von jqno verwendet nämlich die Methode Throwable.getStackTrace(), die Sie in Ihrer Frage angegeben haben, während Brian dies nicht tut. Er verwendet stattdessen Throwable.printStackTrace().
10 Stimmen
So gut wie jedes Java-Projekt sollte Apache commons-lang enthalten. Es enthält viele bequeme Methoden, die extrem häufige Entwicklungsanforderungen implementieren.
20 Stimmen
@StijndeWitt Diese drei Codezeilen müssen mit ziemlicher Sicherheit von der Stelle, an der Sie sie aufgerufen haben, ausgeklammert werden. Da Sie nicht wissen, wohin sie gehören, landen sie in Ihrer Utility-Toolbox mit all den anderen nützlichen Schnipseln. Bingo! Sie haben gerade Guava / Commons-Lang / was auch immer neu erfunden... nur nicht so gut. Importieren Sie stattdessen eine vernünftige Utility-Bibliothek und erfinden Sie das Rad nicht neu. Das wahre Zeichen eines Anfängers ist es, zu glauben, dass man es besser machen kann als die Autoren der Bibliothek.
2 Stimmen
NB: Das Prinzip der einzigen Abstraktionsebene ist der Grund dafür, dass diese Art von Dingen nicht berücksichtigt werden sollte. Erleichtert die Lesbarkeit und Testbarkeit, deckt wiederverwendbare Elemente auf. Siehe: slideshare.net/guestebde/10-ways-to-improve-your-code-
16 Stimmen
@AndrewSpencer Ich verstehe nicht, warum ihr so sehr versucht, StijndeWitt dafür zu beschimpfen, dass er dies mit einem kleinen Schnipsel erreichen will. Es besteht wirklich keine große Gefahr, eine winzige Utility-Methode zu schreiben (ich sehe es nicht als "Reine ARROGANZ, oh nein, er denkt, er sei besser als Apache"). Es gibt tonnenweise Projekte, vor allem in Nicht-Java-JVM-Sprachen, die wirklich nicht Guava oder Commons Lang einbinden wollen, nur um einen Stacktrace zu protokollieren. Ich schreibe Scala- und Clojure-Bibliotheken und werde sicherlich nicht Apache Commons Lang zu einer transitiven Abhängigkeit nur für eine Methode machen.
1 Stimmen
@jm0 Kein Bashing, nur eine qualifizierte Meinungsverschiedenheit. Es war ein bisschen zu schnippisch, ich war auf einen Kampf aus, nachdem ich einige schlechte selbstgebaute Dienstprogramme gesehen hatte. Ich stimme zu, dass es Gründe gibt, eine Abhängigkeit nicht hinzuzufügen, ich sehe nur häufiger den gegenteiligen Fehler.
0 Stimmen
@Gewure Unser Wissen und unser Verständnis des Codes sind heute so viel weiter entwickelt und fortgeschritten. Wir brauchen solche belanglosen Fragen nicht mehr. Lasst das gemeine Volk in seinen Unzulänglichkeiten verrotten.
1 Stimmen
Ich bin hierher gekommen, weil man beim Schreiben von Amazon Lambda-Funktionen in Java den Import von Bibliotheken vermeiden sollte, da sie die Startzeit des Containers in die Höhe treiben. Manchmal ist es also notwendig, das Rad neu zu erfinden. Oder vielleicht könnte ich das mit ProGuard lösen...
0 Stimmen
@Andrew ich weiß nicht, ob ich deinen Sarkasmus? richtig interpretiere, aber ich denke, du hast mich auch nicht richtig interpretiert: Ich wollte sagen, dass SO ein Problem hat. Es ist in der Tat elitär geworden. Es versagt völlig dabei, eine Verbindung für Neulinge zu öffnen. Sie wollten z.B. kein nicht-englisches SO. Das ist undemokratisch und elitär. Es gibt Leute, die programmieren können/wollen, aber kein richtiges Englisch sprechen.
1 Stimmen
@Gewure Es wäre hilfreich gewesen, wenn du deinen Kommentar nicht gelöscht hättest... Es war aber offensichtlich Sarkasmus. S.O. war schon immer voll von elitären und engstirnigen Snobs. Das ist nicht wirklich die Schuld von S.O., denke ich, sondern nur ein allgemeiner Fehler der Menschheit, der hier sehr deutlich zur Schau gestellt wird. Was die englische Sprache betrifft, so gibt es auf beiden Seiten eine gewisse Sensibilität; ich kann allerdings nur über das Argument selbst sprechen.
3 Stimmen
Verwenden Sie commons-lang. Josh Bloch sagt: "Wenn Sie etwas tun müssen, das relativ häufig vorkommt, gibt es vielleicht schon eine Klasse in den Bibliotheken, die das tut, was Sie wollen. Wenn das der Fall ist, verwenden Sie sie; wenn Sie es nicht wissen, überprüfen Sie es.[...]Bibliothekscode ist wahrscheinlich besser als Code, den Sie selbst schreiben würden, und wird wahrscheinlich im Laufe der Zeit verbessert.Das ist keine Aussage über Ihre Fähigkeiten als Programmierer.Skaleneffekte diktieren, dass Bibliothekscode weit mehr Aufmerksamkeit erhält, als die meisten Entwickler es sich leisten könnten, der gleichen Funktionalität zu widmen."