Frage

Ich hatte Fälle von unserem Java -Code Catch a NullPointerException, aber wenn ich versuche, den Stacktrace zu protokollieren (was im Grunde genommen ruft Throwable.printStackTrace() ), alles was ich bekomme ist:

java.lang.NullPointerException

Hat noch jemand darauf gestoßen? Ich habe versucht, nach "Java Null Zeiger leerer Stack Trace" zu googeln, stieß aber nicht auf so etwas.

War es hilfreich?

Lösung

Sie verwenden wahrscheinlich den Hotspot JVM (ursprünglich von Sun Microsystems, später von Oracle, Teil des OpenJDK), das viel Optimierung durchführt. Um die Stapelspuren zurückzubekommen, müssen Sie die Option übergeben -XX:-OmitStackTraceInFastThrow zum JVM.

Die Optimierung besteht darin, dass beim ersten Mal eine Ausnahme (typischerweise eine Nullpointerexception) auftritt, die vollständige Stapelverfolgung gedruckt und die JVM an die Stapelspur (oder vielleicht nur an den Ort des Code) erinnert. Wenn diese Ausnahme oft genug auftritt, wird die Stapelspur nicht mehr gedruckt, um eine bessere Leistung zu erzielen und das Protokoll nicht mit identischen Stapelspuren zu überfluten.

Um zu sehen, wie dies im Hotspot JVM implementiert wird, Schnapp dir eine Kopie davon und suchen Sie nach der globalen Variablen OmitStackTraceInFastThrow. Das letzte Mal, als ich mir den Code (im Jahr 2019) angesehen habe, war er in der Datei graphkit.cpp.

Andere Tipps

Wie Sie in einem Kommentar erwähnt haben, verwenden Sie log4j. Ich entdeckte (versehentlich) einen Ort, an dem ich geschrieben hatte

LOG.error(exc);

statt der typischen

LOG.error("Some informative message", e);

durch Faulheit oder vielleicht einfach nicht darüber nachdenken. Der unglückliche Teil davon ist, dass es sich nicht so verhalten, wie Sie es erwarten. Die Logger -API nimmt das Objekt tatsächlich als erstes Argument, nicht als Zeichenfolge - und ruft dann zum Argument tostring () auf. Anstatt die schöne hübsche Stapelspur zu bekommen, druckt es nur das Tastring aus - was im Fall von NPE ziemlich nutzlos ist.

Vielleicht ist das, was Sie erleben?

Wir haben das gleiche Verhalten in der Vergangenheit gesehen. Es stellte sich heraus, dass aus irgendeinem verrückten Grund eine Nullpointerexception am selben Ort im Code mehrmals nach einer Weile auftrat Log.error(String, Throwable) Ich würde aufhören, vollständige Stapelspuren aufzunehmen.

Versuchen Sie, in Ihr Protokoll weiter zu schauen. Sie können den Täter finden.

BEARBEITEN: Dieser Fehler Klingt relevant, aber es wurde vor so langer Zeit behoben, dass es wahrscheinlich nicht die Ursache ist.

Hier ist eine Erklärung: Hotspot führte dazu, dass Ausnahmen ihre Stapelspuren in der Produktion verlor - und die Fix

Ich habe es auf Mac OS X getestet

  • Java -Version "1.6.0_26"
  • Java (TM) SE-Laufzeitumgebung (Build 1.6.0_26-B03-383-11A511)
  • Java Hotspot (TM) 64-Bit-Server VM (Build 20.1-B02-383, gemischter Modus)

    Object string = "abcd";
    int i = 0;
    while (i < 12289) {
        i++;
        try {
            Integer a = (Integer) string;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

Für dieses spezifische Codefragment scheinen 12288 Iterationen (+Frequenz?) Die Grenze zu sein, bei der JVM beschlossen hat, eine preallozierte Ausnahme zu verwenden ...

exception.toString gibt Ihnen nicht die Stacktrace, sie kehrt nur zurück

Eine kurze Beschreibung dieses Throwable. Das Ergebnis ist die Verkettung von:

* the name of the class of this object
* ": " (a colon and a space)
* the result of invoking this object's getLocalizedMessage() method

Verwenden exception.printStackTrace Stattdessen die Stacktrace ausgeben.

Alternativer Vorschlag - Wenn Sie Eclipse verwenden, können Sie einen Haltepunkt auf NullPoInterexception selbst festlegen (in der Debug -Perspektive gehen Sie auf die Registerkarte "Breakpoints" und klicken Sie auf das kleine Symbol, das ein! Darin enthält).

Überprüfen Sie sowohl die "gefangenen" als auch "nicht erfassten" Optionen - jetzt, wenn Sie den NPE auslösen, werden Sie sofort Breakpoint und Sie können dann durchgehen und sehen, wie genau er behandelt wird und warum Sie keine Stapelspur erhalten.

toString() Gibt nur den Ausnahmenamen und die optionale Nachricht zurück. Ich würde vorschlagen, anzurufen

exception.printStackTrace()

Um die Nachricht abzugeben oder wenn Sie die blutigen Details benötigen:

 StackTraceElement[] trace = exception.getStackTrace()

(Ihre Frage ist noch unklar, ob Ihr Code anruft printStackTrace() oder dies wird von einem Protokollierungshandler getan.)

Hier sind einige mögliche Erklärungen darüber, was passieren könnte:

  • Der verwendete Logger / Handler wurde so konfiguriert, dass er nur die Meldungszeichenfolge der Ausnahme und keine vollständige Stapelspur ausgibt.

  • Ihre Anwendung (oder eine Bibliothek von Drittanbietern) protokolliert die Ausnahme mithilfe LOG.error(ex); anstelle der 2-Argument-Form von (zum Beispiel) der Log4j-Logger-Methode.

  • Die Nachricht kommt von einem anderen Ort, an dem Sie denkst, wo Sie denken. ZB, z. B. gibt es tatsächlich eine Bibliotheksmethode von Drittanbietern oder einige zufällige Dinge, die aus früheren Versuchen zum Debuggen übrig sind.

  • Die Ausnahme, die protokolliert wird, hat einige Methoden überlastet, um die Stacktrace zu verdecken. Wenn dies der Fall ist, ist die Ausnahme keine echte NullPointerexception, sondern ein benutzerdefinierter Subtyp von NPE oder sogar eine nicht verbundene Ausnahme.

Ich denke, dass die letzte mögliche Erklärung ziemlich unwahrscheinlich ist, aber die Leute denken zumindest darüber nach, solche Dinge zu tun, um Reverse Engineering zu verhindern. Natürlich gelingt es nur wirklich, ehrlichen Entwicklern das Leben schwer zu machen.

Wenn Sie Aspekte in Ihrem Projekt verwenden, kann es passieren, dass einige Aspekte seinen Teil der Stapelspur verbirgen. Zum Beispiel hatte ich heute:

java.lang.NullPointerException:
  at com.company.product.MyTest.test(MyTest.java:37)

Diese Stapelverfolgung wurde gedruckt, als der Test über Mavens Surefire ausgeführt wurde.

Andererseits wurde bei der Durchführung des Tests in Intellij eine andere Stapelspur gedruckt:

java.lang.NullPointerException
  at com.company.product.library.ArgumentChecker.nonNull(ArgumentChecker.java:67)
  at ...
  at com.company.product.aspects.CheckArgumentsAspect.wrap(CheckArgumentsAspect.java:82)
  at ...
  at com.company.product.MyTest.test(MyTest.java:37)

Dadurch wird die Ausnahme ausgegeben und nur zum Debuggen verwendet. Sie sollten Ihre Ausnahmen besser behandeln.

import java.io.PrintWriter;
import java.io.StringWriter;
    public static String getStackTrace(Throwable t)
    {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        t.printStackTrace(pw);
        pw.flush();
        sw.flush();
        return sw.toString();
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top