NullPointerException w Javie bez StackTrace

Miałem instancje naszego kodu Javy catch a NullPointerException, ale kiedy próbuję zalogować StackTrace (który w zasadzie kończy się wywołaniem Throwable.printStackTrace()), dostaję tylko:

java.lang.NullPointerException
Czy ktoś jeszcze na to wpadł? Próbowałem googling dla "java null pointer empty stack trace", ale nie natknąłem się na coś takiego.

10 answers

Prawdopodobnie używasz Sun JVM, który wykonuje wiele optymalizacji. Aby odzyskać ślady stosu, musisz przekazać opcję -XX:-OmitStackTraceInFastThrow do JVM.

Nowoczesne OpenJDK JVMs (1.8 i wyższe?) wydaje się akceptować również znacznik -XX:-OmitStackTraceInFastThrow (i domyślnie włączoną optymalizację śledzenia stosu).

 284
Author: Roland Illig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-06 03:19:16

Jak wspomniałeś w komentarzu, używasz log4j. odkryłem (nieumyślnie) miejsce, w którym napisałem

LOG.error(exc);

Zamiast typowego

LOG.error("Some informative message", e);
Przez lenistwo, a może po prostu nie myślenie o tym. Niefortunną częścią tego jest to, że nie zachowuje się tak, jak się spodziewasz. Interfejs API loggera przyjmuje obiekt jako pierwszy argument, a nie Łańcuch znaków - a następnie wywołuje ToString () na argumencie. Więc zamiast uzyskać ładny ślad stosu, po prostu drukuje toString - co w przypadku NPE jest dość bezużyteczne. Może właśnie tego doświadczasz?
 52
Author: Steven Schlansker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:50:05

Widzieliśmy to samo zachowanie w przeszłości. Okazało się, że z jakiegoś szalonego powodu, jeśli NullPointerException wystąpiło wielokrotnie w tym samym miejscu w kodzie, po pewnym czasie użycie Log.error(String, Throwable) przestałoby zawierać pełne ślady stosu.

Spróbuj poszukać dalej w swoim dzienniku. Możesz znaleźć winowajcę.

Edytuj: ten błąd brzmi trafnie, ale został naprawiony tak dawno temu, że prawdopodobnie nie jest przyczyną.

 21
Author: Matt Solnit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 00:54:27

Oto Wyjaśnienie: Hotspot spowodował, że wyjątki traciły ślady stosu w produkcji – i poprawka

Testowałem go na Mac OS X

  • wersja java "1.6.0_26"
  • Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11a511)
  • W przeciwieństwie do innych maszyn wirtualnych, nie są one w stanie działać poprawnie.]}
    Object string = "abcd";
    int i = 0;
    while (i < 12289) {
        i++;
        try {
            Integer a = (Integer) string;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

Dla tego konkretnego fragmentu kodu, 12288 iteracji (+frequency?) wydaje się być granicą, w której JVM ma zdecydowano się użyć prealokowanego wyjątku...

 17
Author: Benoît Guérout,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-14 21:37:14

exception.toString nie daje Ci StackTrace, tylko zwraca

Krótki opis tego miotacza. Wynikiem jest konkatenacja:

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

Użycie exception.printStackTrace zamiast tego, aby wyprowadzić StackTrace.

 10
Author: Peter Lang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:30:59

Alternatywna sugestia-jeśli używasz Eclipse, możesz ustawić punkt przerwania na NullPointerException (w perspektywie debugowania przejdź do zakładki " Punkty przerwania "i kliknij małą ikonkę, która ma! in it)

Sprawdź zarówno opcje" caught", jak i" uncaught " - teraz, gdy uruchomisz NPE, natychmiast pojawi się breakpoint, a następnie możesz przejść i zobaczyć, jak dokładnie jest to obsługiwane i dlaczego nie otrzymujesz śledzenia stosu.

 4
Author: Steven Schlansker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 20:14:04

toString() zwraca tylko nazwę wyjątku i opcjonalną wiadomość. Proponuję zadzwonić

exception.printStackTrace()

Aby zrzucić wiadomość, lub jeśli potrzebujesz krwawe szczegóły:

 StackTraceElement[] trace = exception.getStackTrace()
 1
Author: Sheldon Young,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:27:44

(twoje pytanie jest nadal niejasne, czy Twój kod wywołuje printStackTrace(), czy jest to wykonywane przez obsługę logowania.)

Oto kilka możliwych wyjaśnień na temat tego, co może się dziać:

  • Używany logger / handler został skonfigurowany tak, aby wypisywał tylko ciąg wiadomości wyjątku, a nie Pełny ślad stosu.

  • Twoja aplikacja (lub jakaś biblioteka innej firmy) rejestruje wyjątek używając LOG.error(ex);, a nie 2-argumentowej formy (na przykład) metoda Log4j Logger.

  • Wiadomość pochodzi z innego miejsca, niż myślisz, że jest; np. rzeczywiście pochodzi z jakiejś innej metody bibliotecznej lub losowych rzeczy pozostawionych po wcześniejszych próbach debugowania.

  • Wyjątek, który jest rejestrowany, przeciążył niektóre metody, aby zasłonić stacktrace. Jeśli tak się stanie, wyjątek nie będzie prawdziwym wyjątkiem NullPointerException, ale będzie jakimś niestandardowym podtypem NPE lub nawet jakimś niepodłączonym wyjątek.

Myślę, że ostatnie możliwe wyjaśnienie jest mało prawdopodobne, ale ludzie przynajmniej rozważają zrobienie tego rodzaju rzeczy, aby "zapobiec" inżynierii odwrotnej. Oczywiście tylko naprawdę udaje się utrudnić życie uczciwym programistom.
 1
Author: Stephen C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 22:51:29

To wyświetli wyjątek, użyj tylko do debugowania powinieneś lepiej obsługiwać wyjątki.

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();
    }
 0
Author: Michael D. Irizarry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-09 18:31:09

Kiedy używasz AspectJ w swoim projekcie, może się zdarzyć, że jakiś aspekt ukryje jego część śladu stosu. Na przykład dzisiaj miałem:

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

Ten ślad stosu został wydrukowany podczas uruchamiania testu przez surefire Mavena.

Z drugiej strony, podczas uruchamiania testu w IntelliJ, Wydrukowano inny ślad stosu:

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)
 0
Author: Roland Illig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-07 13:16:59