Ausnahme ohne Stacktrace in Java

Lesezeit: 5 Minuten

Benutzer-Avatar
Michael

Das ist wahrscheinlich eine sehr naive Frage.

Früher habe ich geglaubt, dass a Throwable auf Java stets enthält den Stacktrace. Ist es richtig?

Jetzt sieht es so aus, dass ich Ausnahmen fange ohne der Stack-Trace. Macht das Sinn? Ist es möglich um eine Ausnahme ohne Stack-Trace abzufangen?

  • Welche JVM? Umfeld? usw. Hilft das? stackoverflow.com/questions/4659151/…

    – N.G.

    11. Juli 2012 um 14:07 Uhr

  • @SB. Ja, das hilft. Danke vielmals. Ich habe ein sehr ähnliches Problem: Ich habe viele Ausnahmen (NPE). Methode error von log4j protokolliert einige Ausnahmen ohne der Stack-Trace.

    – Michael

    11. Juli 2012 um 14:25 Uhr


Benutzer-Avatar
Alex W

Es ist möglich, ein Throwable-Objekt in Java ohne Stacktrace abzufangen:

Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace) 

Erstellt ein neues Throwable mit der angegebenen Detailmeldung, Ursache, Unterdrückung aktiviert oder deaktiviert und
Beschreibbarer Stack-Trace aktiviert oder deaktiviert.

public Throwable fillInStackTrace()

Füllt den Ausführungsstack-Trace aus. Diese Methode zeichnet in diesem Throwable-Objekt Informationen über den aktuellen Zustand der Stack-Frames für den aktuellen Thread auf.

Wenn der Stack-Trace dieses Throwable nicht beschreibbar ist, hat der Aufruf dieser Methode keine Auswirkung.

http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html

  • Es sagt nur, dass “schreibbarer Stack-Trace” aktiviert oder deaktiviert ist. Ich glaube nicht, dass dies bedeutet, dass der Stack-Trace nicht erfasst wird

    – MatanCo

    19. Juni 2019 um 9:18 Uhr

  • Bedeutet dies, dass es nicht generiert wird und der Prozess viel schneller ist?

    – Paulus

    16. Oktober 2019 um 9:33 Uhr

  • Die Dokumentation für writableStackTrace sagt dies: “ob der Stack-Trace sein soll oder nicht schreibbar“. Daher verhindert dieser Parameter NICHT, dass Stack-Traces generiert werden. Ich sehe nicht, wie dieser Beitrag die Frage beantwortet. Bitte korrigieren oder löschen Sie diese Antwort!

    – Lii

    1. April 2020 um 11:52 Uhr


  • Bitte lesen Sie die Frage. OP fragt, ob es möglich ist, einen zu fangen Throwable ohne Stacktrace. Die Antwort ist natürlich ja. Direktes Zitat aus Dokumentation für fillInStackTrace: “Füllt den Stack-Trace der Ausführung. Diese Methode zeichnet in diesem Throwable-Objekt Informationen über den aktuellen Status der Stack-Frames für den aktuellen Thread auf. Wenn der Stack-Trace dieses Throwable nicht beschreibbar ist, hat der Aufruf dieser Methode keine Auswirkung.”

    – Alex W

    15. Mai 2020 um 17:47 Uhr

Benutzer-Avatar
manikanta

Für Java6:

Da Java 6 das nicht hat Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace) Konstruktor können wir das Füllen des Stacktrace mit der folgenden Technik unterdrücken (von Scala entlehnt, erfuhr ich von Wie langsam sind Java-Ausnahmen?).

class NoStackTraceRuntimeException extends RuntimeException {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

Verwendung ist gleich: throw new NoStackTraceRuntimeException ()oder seine Subtypen.

Dasselbe können wir auch tun, indem wir verlängern Throwable:

class NoStackTraceThrowable extends Throwable {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

Aber ein kleiner Haken ist, dass Sie nicht mehr können catch diese Ausnahme mit Exception da dies kein Untertyp von ist Exceptionsollte stattdessen fangen NoStackTraceThrowable oder es ist Untertypen.

Aktualisieren: Einige interessante Statistiken zur Leistung in verschiedenen Anwendungsfällen finden Sie in dieser SO-Frage

  • @shekharsuman Nein, aber auch kein Java 7. Diese Antwort könnte jemandem mit Java 6 helfen 🙂

    – manikanta

    15. August 2014 um 10:09 Uhr

  • Auch außerhalb von Java 1.6 ist dies immer noch eine praktikable Methode. Dadurch wird der gesamte Stack-Trace unterdrückt (da die übergebene Ursache des Konstruktors mit 4 Parametern ausgegeben wird).

    – DBK

    8. Mai 2015 um 13:17 Uhr

  • Ich benutze hier im Jahr 2016 immer noch Java 6, also ja :/

    – Karl Holz

    23. März 2016 um 22:01 Uhr

  • Dein NoStackTraceThrowable verlängern könnte Exception stattdessen (und angerufen werden NoStackTraceException), wenn Sie wollten, dass es von a gefangen wird catch (Exception) Block.

    – dimo414

    3. April 2016 um 17:11 Uhr

  • Es besteht keine Notwendigkeit, eine Methode zu markieren, die lediglich zurückkehrt this wie synchronized.

    – Holger

    1. November 2019 um 16:33 Uhr

Benutzer-Avatar
Deron

Für Java 7+ ist hier ein Beispiel für eine Ausnahme, bei der der Stack-Trace optional unterdrückt werden kann.

public class SuppressableStacktraceException extends Exception {

    private boolean suppressStacktrace = false;

    public SuppressableStacktraceException(String message, boolean suppressStacktrace) {
        super(message, null, suppressStacktrace, !suppressStacktrace);
        this.suppressStacktrace = suppressStacktrace;
    }

    @Override
    public String toString() {
        if (suppressStacktrace) {
            return getLocalizedMessage();
        } else {
            return super.toString();
        }
    }
}

Dies kann demonstriert werden mit:

try {
    throw new SuppressableStacktraceException("Not suppressed", false);
} catch (SuppressableStacktraceException e) {
    e.printStackTrace();
}
try {
    throw new SuppressableStacktraceException("Suppressed", true);
} catch (SuppressableStacktraceException e) {
    e.printStackTrace();
}

Dies basiert auf der MLContextException von Apache SystemMLdessen Code auf GitHub unter verfügbar ist https://github.com/apache/systemml.

  • Ordentlich, das Entfernen von toString() bietet mir immer noch genug Unterdrückung.

    – Benny Bottema

    9. Oktober 2019 um 9:16 Uhr

  • Warum entlarvst du kein Contructor-Argument, das ein Throwable nehmen würde?

    – Ihor M.

    16. Dezember 2019 um 21:10 Uhr

  • Warum impliziert supressStackTrace das Argument supressedException in Exception?

    – Whimusical

    21. April 2020 um 11:00 Uhr

  • Warum müssen Sie überschreiben toString?

    – JojOatXGME

    26. Mai 2021 um 9:40 Uhr

Benutzer-Avatar
Stefan Isele – prefabware.com

Der einfachste Weg, den Stacktrace bei jeder Ausnahme zu unterdrücken, ist

throwable.setStackTrace(new StackTraceElement[0]);

Wenn die Ausnahme eine Ursache hat, müssen Sie möglicherweise rekursiv dasselbe tun.

Dadurch wird auch die aufwendige Erstellung des Stack-Trace so weit wie möglich reduziert

Der Stacktrace für ein Throwable wird in initialisiert

Throwable#fillInStackTrace()

, die von jedem Konstruktor aufgerufen wird und daher nicht vermieden werden kann. Wenn der Stacktrace tatsächlich verwendet wird, ist ein StackTraceElement[] ist faul eingebaut

Throwable#getOurStackTrace()

was nur passiert, wenn das Feld Throwable.stackTrace nicht bereits gesetzt wurde.

Durch Festlegen des Stacktrace auf einen beliebigen Nicht-Nullwert wird die Konstruktion des StackTraceElement vermieden[] in Throwable#getOurStackTrace() und reduziert die Leistungseinbußen so weit wie möglich.

Wie in der Antwort von NG. angedeutet, wenn Sie zuerst den Stacktrace sehen, dann aber für dieselbe Ausnahme verschwindet, sehen Sie höchstwahrscheinlich die Auswirkungen der JVM-Optimierung. In diesem Fall sind die folgenden Fragen sehr ähnlich.

Wiederkehrende Ausnahme ohne Stack-Trace – wie zurücksetzen?

NullPointerException in Java ohne StackTrace

Sie können diese JVM-Funktion deaktivieren, aber ich würde empfehlen, sie aktiviert zu lassen und daran zu arbeiten, den Fehler von vornherein zu verhindern, oder ihn abzufangen und eleganter zu handhaben.

1019400cookie-checkAusnahme ohne Stacktrace in Java

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy