2012-09-11 3 views
4

У меня есть следующий код:Java Exception StackTrace Не Печать

import org.apache.commons.lang.exception.ExceptionUtils; 
public void myMethod() { 
    try { 
     // do something 
    } catch (Exception e) { 
     System.out.println(ExceptionUtils.getStackTrace(e)); // prints "java.lang.NullPointerException" 
     System.out.println(ExceptionUtils.getFullStackTrace(e)); // prints "java.lang.NullPointerException" 
     e.printStackTrace(); // prints "java.lang.NullPointerException" 
    } 
} 

Вывод, который я хотел бы видеть это полный StackTrace с номерами строк и иерархия классов, которые не удалось. Например,

Exception in thread "main" java.lang.NullPointerException 
     at org.Test.myMethod(Test.java:674) 
     at org.TestRunner.anotherMethod(TestRunner.java:505) 
     at java.util.ArrayList(ArrayList.java:405) 

Этот код в настоящее время работают в большем приложение, которое также имеет log4j, но я надеюсь, чтобы иметь возможность получить исключение в строку, так что я могу отправить его по электронной почте на Java Разработчики.

Есть ли у кого-нибудь идеи о том, как я могу захватить полную трассировку стека в строку? Я не могу использовать Thread.currentThread(). GetStackTrace(), поскольку это приложение работает на Java 4. Что может блокировать вышеуказанный код от печати полного stacktrace?

+0

Похоже, что массив StackTraceElement в NPE сбрасывается на пустой. Что-нибудь вызывает setStackTrace на NPE? –

+0

@DanGravell - Нет, ничто не должно вызывать setStackTrace. – David

+0

Вы можете отлаживать это в среде IDE? Возможно, стоит установить контрольную точку в блоке catch, чтобы убедиться, что Exception «отлично сформирован». –

ответ

2

Исключение может быть пойманы и брошенные где-то до вашего улова блока. Может быть, в другом классе, который вы призываете делать логикой.

Exception созданный как
new Exception(new Throwable("java.lang.NullPointerException"));
напечатает что-то похожее на то, что вы видите.

+0

Получилось, что внутри блока try он совершил вызов другого метода, у которого был блок try с оператором catch, который явно уменьшил исключение (аналогично вашему примеру, за исключением того, что они не жестко кодировали «NullPointerException», , а скорее просто урезал причину stacktrace). – David

+0

@David - Я бы серьезно подумал о переходе на другой продукт. Умышленное подавление подобной информации исключений противоречит интересам своих клиентов/пользователей. Найдите альтернативного поставщика, который не делает этого дрянного. –

1

Может быть, у вас нет приложения для вывода консоли. Вы можете добавить его. Если нет, зарегистрируйте его как LOGGER.error (ex); с log4j или SLF4J

+0

Некоторое время я думал, что это может быть связано с консольным протоколированием. Поэтому я попытался сохранить исключение в строке и отправить его по электронной почте. В электронном письме содержалось только «java.lang.NullPointerException» – David

9

Если вы повторно бросаете исключение, JVM перестает заполнять трассировку стека. Я не уверен, почему, но это может быть, чтобы уменьшить нагрузку на JVM. Вам нужно посмотреть предыдущую трассировку стека, чтобы увидеть детали.

for (int n = 0; ; n++) { 
    try { 
     Integer i = null; 
     i.hashCode(); 
    } catch (Exception e) { 
     if (e.getStackTrace().length == 0) { 
      System.out.println("No more stack trace after " + n + " thrown."); 
      break; 
     } 
    } 

печатает

No more stack trace after 20707 thrown. 
+1

, это было так, слишком много исключений слишком быстро выросло. – PUG

1

Я могу думать только о 2 причинах, почему e.printStackTrace() может выводить только строку "java.lang.NullPointerException".

  • Что-то, возможно, вызвало setStackTrace(new StackTraceElement[0]) по исключению.
  • Объект исключения может быть экземпляром сложного класса, который переопределил printStackTrace() или какой-либо другой метод, чтобы вернуть вводящую в заблуждение информацию.
12

Это beacause java делает некоторую оптимизацию кода при запуске в режиме сервера (java-servererver) , чтобы пропустить это. использовать -XX:-OmitStackTraceInFastThrow в ява арг см ссылку ниже для деталей:

http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/

+0

Вместо того, чтобы отключать эту оптимизацию на производственном сервере, я просто буду следовать совету Питера и посмотреть на более раннюю ошибку в журнале. –

+0

Я согласен, что это можно сделать, когда вы владеете кодом, если вы зависите от кого-то еще, пока не исправит, это лучшее, что вы могли бы сделать. – vinesh

+0

Это определенно то, что вызвало аналогичную проблему для меня на Prod. Спасибо за ответ! – dpetruha

2

Кто-нибудь есть какие-либо идеи о том, как я могу захватить полный трассировки стека в строку?

Вы можете использовать способ ниже (StringWriter.toString()) для переноса трассировки стека в строку.

StringWriter writer = new StringWriter(); 
e.printStackTrace(new PrintWriter(writer,true)); 
System. out.println("exeption stack is :\n"+writer.toString()); 
Смежные вопросы