Исключение NullPointerException в Java без трассировки стека



у меня были экземпляры нашего кода Java catch a NullPointerException, но когда я пытаюсь войти в StackTrace (который в основном заканчивается вызовом Throwable.printStackTrace() ), все что я получаю это:



java.lang.NullPointerException


кто-нибудь сталкивался с этим? Я попытался погуглить для "java null pointer empty stack trace", но не наткнулся ни на что подобное.

503   10  

10 ответов:

вы, вероятно, используете Sun JVM, который выполняет много оптимизации. Чтобы вернуть трассировки стека, вам нужно передать опцию -XX:-OmitStackTraceInFastThrow к JVM.

современные OpenJDK JVMs (1.8 и выше?), кажется, принять -XX:-OmitStackTraceInFastThrow флаг также (и оптимизация трассировки стека включена по умолчанию), а также.

Как вы упомянули в комментарии, что вы при помощи log4j. Я обнаружил (случайно) место, где я написал

LOG.error(exc);

вместо обычного

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

из-за лени или, возможно, просто не думая об этом. К сожалению, он ведет себя не так, как вы ожидаете. API logger фактически принимает объект в качестве первого аргумента, а не строки, а затем вызывает toString() в аргументе. Так что вместо того, чтобы получить хороший довольно трассировки стека, он просто распечатывает toString - что в случае NPE довольно бесполезно.

возможно, это то, что вы испытываете?

мы видели такое же поведение в прошлом. Оказалось, что по какой-то безумной причине, если NullPointerException произошло в одном и том же месте в коде несколько раз, через некоторое время с помощью Log.error(String, Throwable) перестанет включать полные трассировки стека.

попробуйте заглянуть дальше в свой журнал. Вы можете найти виновника.

EDIT:эта ошибка звучит актуально, но это было исправлено так давно, что это, вероятно, не причина.

вот объяснение : Hotspot вызвал исключения, чтобы потерять их трассировки стека в производстве-и исправить

Я тестировал его на Mac OS X

  • java версия "1.6.0_26"
  • Java (TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
  • Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 20.1-b02-383, смешанный режим)

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

для этого конкретного фрагмента кода, 12288 итераций (+частота?) кажется, это предел, когда JVM решила использовать предварительно выделенное исключение...

exception.toString не дает вам StackTrace, он только возвращает

краткое описание этого throwable. Результатом является конкатенация:

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

использовать exception.printStackTrace вместо того, чтобы вывести StackTrace.

альтернативное предложение-если вы используете Eclipse, вы можете установить точку останова на самом NullPointerException (в перспективе отладки перейдите на вкладку "точки останова" и нажмите на маленький значок, который имеет! в нем)

проверьте оба варианта" пойман "и" неперехвачен " - теперь, когда вы запускаете NPE, вы сразу же остановитесь, и вы можете пройти через него и посмотреть, как именно он обрабатывается и почему вы не получаете трассировку стека.

toString() возвращает только имя исключения и дополнительное сообщение. Я бы предложил позвонить

exception.printStackTrace()

сбросить сообщение, или если вам нужны подробности:

 StackTraceElement[] trace = exception.getStackTrace()

(Ваш вопрос все еще неясен о том, вызывает ли ваш код printStackTrace() или это делается обработчик logging.)

вот некоторые возможные объяснения того, что может произойти:

  • используемый регистратор / обработчик был настроен только для вывода строки сообщения исключения, а не полной трассировки стека.

  • ваше приложение (или какая-то сторонняя библиотека) регистрирует исключение с помощью LOG.error(ex); а чем 2-аргументная форма (например) метода log4j Logger.

  • сообщение приходит откуда-то из другого места, где вы думаете, что это; например, это на самом деле приходит какой-то сторонний метод библиотеки, или некоторые случайные вещи, оставшиеся от предыдущих попыток отладки.

  • исключение, которое регистрируется, перегружает некоторые методы, чтобы скрыть трассировку стека. Если это так, исключение не будет подлинным NullPointerException, но будет какой-то пользовательский подтип NPE или даже какое-то несвязанное исключение.

это выведет исключение, используйте только для отладки вы должны обрабатывать исключения лучше.

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();
    }

когда вы используете AspectJ в своем проекте, может случиться так, что какой-то аспект скрывает свою часть трассировки стека. Например, сегодня у меня было:

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

эта трассировка стека была напечатана при запуске теста через surefire Maven.

С другой стороны, при выполнении теста в IntelliJ была напечатана другая трассировка стека:

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)

Comments

    Ничего не найдено.