2010-06-03 127 views
37

的問題很簡單,我想讀的異常的全堆棧跟蹤,我捕捉:)如何打印完整的堆棧跟蹤Java中

例如:

org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot load JDBC driver class 'com.ibm.db2.jcc.DB2Driver' 
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1136) 
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880) 
at com.azurian.lce.usuarios.ConnectionManager.getConnection(ConnectionManager.java:65) 
at com.azurian.lce.usuarios.db2.UsuarioDAOImpl.autenticar(UsuarioDAOImpl.java:101) 
at com.azurian.lce.usuarios.UsuarioServiceImpl.autenticar(UsuarioServiceImpl.java:31) 
at com.azurian.lce.web.admin.actions.LoginAction.execute(LoginAction.java:49) 
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484) 
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274) 
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482) 
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
at java.lang.Thread.run(Unknown Source) 
Caused by: java.lang.ClassNotFoundException: COM.ibm.db2.jcc.DB2Driver 
at java.net.URLClassLoader$1.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.net.URLClassLoader.findClass(Unknown Source) 
at java.lang.ClassLoader.loadClass(Unknown Source) 
at java.lang.ClassLoader.loadClass(Unknown Source) 
at java.lang.ClassLoader.loadClassInternal(Unknown Source) 
at java.lang.Class.forName0(Native Method) 
at java.lang.Class.forName(Unknown Source) 
at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1130) 
... 23 more 

(我想讀「...... 23多個」)

問候:)

+2

Gahhhh ......如此多的運行和進程,調用和執行以及DOS ... http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns。 html – naiad 2010-06-03 22:57:38

+1

請參閱:http://stackoverflow.com/questions/1167888/howto-increase-lines-of-java-stack-trace-dump和 http://stackoverflow.com/questions/1043378/print-full-call -stack-on-printstacktrace和 http://stackoverflow.com/questions/437756/how-do-i-stop-stacktraces-truncating-in-logs只列出幾個 – akf 2010-06-03 23:18:18

+0

嗨! 看看http://people.inf.elte.hu/balopat/bug.html我生成了你,將鼠標懸停在圓圈上,我希望它能幫助你理解'... 23更多'的意思:) 基本上答案是真的,這只是一個例證。 – 2010-06-22 14:56:47

回答

29

答案很簡單,那些線已經在堆棧跟蹤:)

at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:880) 
at com.azurian.lce.usuarios.ConnectionManager.getConnection(ConnectionManager.java:65) 
at com.azurian.lce.usuarios.db2.UsuarioDAOImpl.autenticar(UsuarioDAOImpl.java:101) 
at com.azurian.lce.usuarios.UsuarioServiceImpl.autenticar(UsuarioServiceImpl.java:31) 
at com.azurian.lce.web.admin.actions.LoginAction.execute(LoginAction.java:49) 
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484) 
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274) 
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482) 
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
at java.lang.Thread.run(Unknown Source) 

基本上,以下是發生在BasicDataSource#createDataSource()

try { 
    Class.forName(driverClassName); // Line 1130 
} catch (ClassNotFoundException e) { 
    throw new SQLNestedException(e, "Cannot load JDBC driver class '" + driverClassName + "'"); // Line 1136 
} 
+1

怎麼樣? [....] – OscarRyz 2010-06-03 22:59:05

+0

嗯,現在當很長一段時間過去了,我讀到答案非常簡單,這是一個瓶子問題(或者在這種情況下,它缺少DB2驅動程序的jar,它在: 「引起:java.lang.ClassNotFoundException:COM.ibm.db2.jcc.DB2Driver」 – 2013-08-27 12:35:43

+1

對我來說,這並不回答這個問題。是的,這些行已經在堆棧跟蹤中,但它們沒有被打印出來! 如何打印出來是一個問題,你根本沒有回答! – plainOldNerd 2017-05-17 18:54:43

24

BalusC是正確的。在這裏看到:http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html#printStackTrace()

特別是:

注含 字符線的存在 「...」。這些線 表明 堆棧跟蹤此例外的其餘部分相匹配 從 ,其通過本 異常(以下簡稱「封閉」的異常)引起的異常 的堆棧跟蹤底部的指示的數量的幀。 此速記可以極大地減少 常見的 情況下的輸出長度,其中包裝的例外是 ,與 引發的「引發異常」相同。

這意味着在你的例子是:

BasicDataSource.java線1136抓到扔在行1130 ClassNotFoundException並重新拋出它作爲一個SQLNestedException。因此,ClassNotFoundException的堆棧跟蹤的其餘部分與上面的SQLNestedException相匹配,並且stacktrace以更簡潔的格式打印。

7

當外部異常(SQLNestedException)包裝內部異常(ClassNotFoundError)時,它們位於同一個線程中,因此共享一個公共基址到它們的堆棧跟蹤中。

(23更多...)顯示了公共堆棧啓動內部異常的位置,這也是引發外部異常的地方。所以,無論何時你看到(XX more ......),只要看看上面的異常就可以看到堆棧跟蹤的其餘部分。

如果您想以編程方式打印出沒有常見曲線省略號的堆棧軌跡,那麼您可以使用Throwable.getStackTrace()並自行打印出所有元素。

+0

感謝所有的答案:)它幫助了我很多(瞭解它正在發生什麼,我正在做的程序) 關於 – 2010-06-04 13:47:36

4

試試看。該邏輯遍歷主異常及其所有原因,直到沒有其他原因(cause == null)需要處理。這樣你就可以避免23個以上的信息。我還沒有測試過,但我相信這應該適合你。

順便說一句 - logWriter是一個緩衝作家。您可能想要使用System.out.print或任何其他日誌記錄API。

public static void debugError(final String message, final Throwable th) { 
    final String logMessage = "[ERROR] - " + message; 

    try { 
     logWriter.write(logMessage); 
     logWriter.newLine(); 

     // dump exception stack if specified 
     if (null != th) { 
      final StackTraceElement[] traces = th.getStackTrace(); 
      if (null != traces && traces.length > 0) { 
       logWriter.write(th.getClass() + ": " + th.getMessage()); 
       logWriter.newLine(); 

       for (final StackTraceElement trace : traces) { 
        logWriter.write(" at " + trace.getClassName() + '.' + trace.getMethodName() + '(' + trace.getFileName() + ':' + trace.getLineNumber() + ')'); 
        logWriter.newLine(); 
       } 
      } 

      Throwable cause = th.getCause(); 
      while (null != cause) { 
       final StackTraceElement[] causeTraces = cause.getStackTrace(); 
       if (null != causeTraces && causeTraces.length > 0) { 
        logWriter.write("Caused By:"); 
        logWriter.newLine(); 
        logWriter.write(cause.getClass() + ": " + cause.getMessage()); 
        logWriter.newLine(); 

        for (final StackTraceElement causeTrace : causeTraces) { 
         logWriter.write(" at " + causeTrace.getClassName() + '.' + causeTrace.getMethodName() + '(' + causeTrace.getFileName() + ':' + causeTrace.getLineNumber() + ')'); 
         logWriter.newLine(); 
        } 
       } 

       // fetch next cause 
       cause = cause.getCause(); 
      } 
     } 
    } catch (final IOException ex) { 
     System.err.println(logMessage); 

     if (null != th) { 
      th.printStackTrace(); 
     } 
    } 
} 
+0

您可以使用'Reader'來讀取'printStackTrace'輸出,直到它遇到_Caused by_,然後得到原因並打印它的堆棧跟蹤(尋找下一個_由_引起)...並遞歸地重複這個過程直到出現不再有堆棧痕跡。這樣你就不必建立你自己的定製堆棧跟蹤格式化程序 - 你可以使用已有的':)' – ADTC 2013-08-27 10:28:21

+0

你的代碼運行良好。 要發送跟蹤到system.out,我只需添加 'BufferedWriter logWriter = new BufferedWriter(new OutputStreamWriter(System.out));' 並在結尾: 'logWriter.flush();' – Ben 2018-02-27 16:44:56