У меня были экземпляры нашего Java-кода NullPointerException
, но когда я пытаюсь зарегистрировать StackTrace (который в основном вызывает вызов Throwable.printStackTrace()
), все, что я получаю, это:
java.lang.NullPointerException
Кто-нибудь еще сталкивался с этим? Я пробовал поискать в Google «трассировку пустого стека в пустом указателе Java», но ничего подобного не встречал.
java
nullpointerexception
Эдвард Штерн
источник
источник
-XX:-OmitStackTraceInFastThrow
в дупе: stackoverflow.com/questions/4659151/…Ответы:
Вероятно, вы используете JSM HotSpot (первоначально Sun Microsystems, позже купленную Oracle, часть OpenJDK), которая выполняет большую оптимизацию. Чтобы вернуть трассировку стека, вам нужно передать эту опцию
-XX:-OmitStackTraceInFastThrow
в JVM.Оптимизация заключается в том, что, когда исключение (обычно NullPointerException) возникает впервые, печатается полная трассировка стека, и JVM запоминает трассировку стека (или, возможно, только местоположение кода). Когда это исключение возникает достаточно часто, трассировка стека больше не печатается, чтобы повысить производительность и не заполнять журнал идентичными трассами стека.
Чтобы увидеть, как это реализовано в JVM HotSpot, возьмите его копию и найдите глобальную переменную
OmitStackTraceInFastThrow
. В прошлый раз, когда я посмотрел код (в 2019 году), он был в файле graphKit.cpp .источник
-XX:-OmitStackTraceInFastThrow
флаг. Я еще не подтвердил, если по этой причине я также не смог напечатать трассировки стека (например, используяe.printStackTrace
), но это кажется весьма вероятным. Я расширил ответ, чтобы отразить это открытие.Как вы упомянули в комментарии, вы используете log4j. Я обнаружил (случайно) место, где я написал
вместо типичного
из-за лени или, возможно, просто не думая об этом. К сожалению, это не ведет себя так, как вы ожидаете. API логгера фактически принимает Object в качестве первого аргумента, а не строку, а затем вызывает toString () для аргумента. Таким образом, вместо того, чтобы получить красивую трассировку стека, он просто распечатывает toString - что в случае с NPE довольно бесполезно.
Возможно, это то, что вы испытываете?
источник
Мы видели такое же поведение в прошлом. Оказалось, что по какой-то безумной причине, если исключение NullPointerException происходило в одном и том же месте в коде несколько раз, через некоторое время использование
Log.error(String, Throwable)
перестало бы включать полные трассировки стека.Попробуйте заглянуть дальше в свой журнал. Вы можете найти виновника.
РЕДАКТИРОВАТЬ: эта ошибка звучит актуально, но она была исправлена так давно, что, вероятно, не причина.
источник
-XX:-OmitStackTraceInFastThrow
флаг JVM, предложенный Джошуа? См. Также stackoverflow.com/a/2070568/6198 .Вот объяснение: Hotspot вызвал исключения, чтобы потерять их следы стека в производстве - и исправить
Я проверил это на Mac OS X
Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 20.1-b02-383, смешанный режим)
Для этого конкретного фрагмента кода 12288 итераций (+ частота?), По-видимому, являются пределом, в котором JVM решила использовать предварительно выделенное исключение ...
источник
exception.toString
не дает вам StackTrace, он только возвращаетexception.printStackTrace
Вместо этого используйте для вывода StackTrace.источник
getStackTrace()
чтобы убедиться, что проблема не с вашим регистратором?Альтернативное предложение - если вы используете Eclipse, вы можете установить точку останова на самом NullPointerException (в перспективе Отладка перейдите на вкладку «Точки останова» и нажмите на маленький значок с!)
Проверьте оба параметра: «пойман» и «не пойман» - теперь, когда вы запускаете NPE, вы сразу же получаете точку останова, а затем можете пройти и посмотреть, как именно она обрабатывается и почему вы не получаете трассировку стека.
источник
toString()
возвращает только имя исключения и необязательное сообщение. Я бы предложил позвонитьчтобы выбросить сообщение, или если вам нужны подробности:
источник
(Ваш вопрос до сих пор неясен, звонит ли ваш код
printStackTrace()
или это делает обработчик журналирования.)Вот несколько возможных объяснений того, что может происходить:
Используемый регистратор / обработчик был настроен на вывод только строки сообщения об исключении, а не полной трассировки стека.
Ваше приложение (или некоторая сторонняя библиотека) регистрирует исключение, используя,
LOG.error(ex);
а не 2-аргументную форму (например) метода Log4j Logger.Сообщение приходит откуда-то иное, чем вы думаете; например, это на самом деле какой-то сторонний библиотечный метод или какой-то случайный материал, оставшийся от предыдущих попыток отладки.
Записываемое исключение перегружает некоторые методы, чтобы скрыть трассировку стека. В этом случае исключение не будет подлинным исключением NullPointerException, но будет некоторым пользовательским подтипом NPE или даже каким-то неподключенным исключением.
Я думаю, что последнее возможное объяснение довольно маловероятно, но люди, по крайней мере, обдумывают, что делать, чтобы «предотвратить» обратный инжиниринг. Конечно, только честным разработчикам удается только усложнить жизнь.
источник
Когда вы используете AspectJ в своем проекте, может случиться, что какой-то аспект скрывает свою часть трассировки стека. Например, сегодня у меня было:
Эта трассировка стека была напечатана при запуске теста через верный Maven.
С другой стороны, при запуске теста в IntelliJ была напечатана другая трассировка стека:
источник
Это выведет исключение, используйте только для отладки, вы должны лучше обрабатывать ваши исключения.
источник