2012-09-11 242 views
4

我有以下代碼:Java異常堆棧跟蹤不打印

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" 
    } 
} 

,我想看到的輸出是一個完整的堆棧跟蹤行號和類失敗的層次結構。例如,

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上運行。可能是因爲打印完整堆棧跟蹤而阻止上述代碼?

+0

看起來NPE中的StackTraceElement數組正在被重置爲空。是否有人在NPE上調用setStackTrace? –

+0

@DanGravell - 不,不應該調用setStackTrace。 – David

+0

你能夠在IDE中進行調試嗎?可能值得在catch塊中設置一個斷點,以查看Exception是否「完美形成」。 –

回答

2

的例外可能被捕獲和你的catch塊在什麼地方拋出。也許在另一個你打算去做邏輯的課上。

An Exception創建類似
new Exception(new Throwable("java.lang.NullPointerException"));
將打印出您所看到的內容。

+0

它確實證明了在try塊內部,它調用了另一個具有帶明確減少異常的catch語句的try塊的方法(類似於你的例子,只是它們沒有硬編碼「NullPointerException」 ,而只是截斷了堆棧跟蹤的原因)。 – David

+0

@大衛 - 我會認真考慮切換到不同的產品。故意壓制這種異常信息違背了客戶/用戶的最大利益。找到一個不會做這種糟糕的事情的替代供應商。 –

1

可能是你沒有控制檯輸出一個appender。你考慮加一個。如果不是,則記錄爲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

我只能想到兩個原因爲什麼e.printStackTrace()威力只輸出字符串"java.lang.NullPointerException"

  • 在例外情況下,某物可能會被稱爲setStackTrace(new StackTraceElement[0])
  • 異常對象可能是一個棘手類的實例,它已經重寫了printStackTrace()或其他一些方法來返回誤導性信息。
12

這是因爲java在服務器模式(java -server) 中執行一些代碼優化以跳過此操作。使用-XX:-OmitStackTraceInFastThrow在java中ARGS 詳見下文鏈接:

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