Исключение NullPointerException в Java без трассировки стека
у меня были экземпляры нашего кода Java catch a NullPointerException, но когда я пытаюсь войти в StackTrace (который в основном заканчивается вызовом Throwable.printStackTrace() ), все что я получаю это:
java.lang.NullPointerException
кто-нибудь сталкивался с этим? Я попытался погуглить для "java null pointer empty stack trace", но не наткнулся ни на что подобное.
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