2010-06-03 36 views
37

Câu hỏi đặt ra là đơn giản, tôi muốn đọc stacktrace đầy đủ của một ngoại lệ mà tôi chụp :)cách in đầy đủ stacktrace trong java

dụ:

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 

(i muốn đọc "... hơn 23")

Trân :)

+2

Gahhhh ... rất nhiều lần chạy và xử lý và gọi và thực hiện và thực hiện ... http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns. html – naiad

+1

xem: http://stackoverflow.com/questions/1167888/howto-increase-lines-of-java-stack-trace-dump và http://stackoverflow.com/questions/1043378/print-full-call -stack-on-printstacktrace và http://stackoverflow.com/questions/437756/how-do-i-stop-stacktraces-truncating-in-logs để liệt kê chỉ một vài – akf

+0

Xin chào! Nhìn vào http://people.inf.elte.hu/balopat/bug.html Tôi tạo ra bạn, di chuột qua các vòng tròn, tôi hy vọng nó sẽ giúp bạn hiểu những gì '... 23 more' có nghĩa là :) Về cơ bản các câu trả lời là đúng, đây chỉ là một minh họa. –

Trả lời

29

Câu trả lời rất đơn giản, những dòng đã có trong stacktrace :)

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) 

Về cơ bản, sau đây đang xảy ra trong BasicDataSource#createDataSource():

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

howcome? [....] – OscarRyz

+0

Vâng, bây giờ khi một thời gian dài đã trôi qua tôi đọc rằng câu trả lời rất đơn giản, đó là một vấn đề địa ngục jar (hoặc trong trường hợp này là thiếu jar với trình điều khiển DB2. "Nguyên nhân bởi: java.lang.ClassNotFoundException: COM.ibm.db2.jcc.DB2Driver" –

+1

Điều này, đối với tôi, không trả lời câu hỏi. Có, những dòng đó đã có trong ngăn xếp dấu vết, nhưng chúng không được in! – plainOldNerd

24

BalusC là đúng. Xem ở đây: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html#printStackTrace()

Đặc biệt:

Lưu ý sự hiện diện của các dòng có chứa các nhân vật "...". Những dòng này cho biết phần còn lại của dấu vết ngăn xếp cho ngoại lệ này khớp với số khung được chỉ định từ phần dưới cùng của dấu vết ngăn xếp của trường hợp ngoại lệ này (ngoại lệ "kèm theo"). Cách viết tắt này có thể làm giảm đáng kể chiều dài đầu ra trong trường hợp phổ biến trong trường hợp ngoại lệ được bao bọc là được ném từ cùng một phương thức như là "ngoại lệ gây ra" bị bắt.

Điều này có nghĩa trong ví dụ của bạn là:

BasicDataSource.java dòng 1136 bắt được ClassNotFoundException ném vào dòng 1130, reraised nó như là một SQLNestedException. Do đó phần còn lại của stacktrace cho ClassNotFoundException khớp với SQLNestedException ở trên và stacktrace được in theo định dạng ngắn gọn hơn này.

7

Khi ngoại lệ bên ngoài (SQLNestedException) kết thúc ngoại lệ bên trong (ClassNotFoundError), chúng nằm trên cùng một luồng và chia sẻ cơ sở chung cho dấu vết ngăn xếp của chúng.

(23 hiển thị ...) hiển thị nơi ngăn xếp chung bắt đầu cho ngoại lệ bên trong, cũng là nơi ngoại lệ được ném ra ngoài. Vì vậy, bất cứ khi nào bạn nhìn thấy (XX nhiều hơn ...), chỉ cần nhìn vào ngoại lệ ở trên để xem phần còn lại của dấu vết ngăn xếp.

Nếu bạn muốn in theo lập trình ngăn xếp mà không có dấu ba chấm cho dấu vết phổ biến, thì bạn có thể sử dụng Throwable.getStackTrace() và tự in tất cả các phần tử.

+0

nhờ tất cả các câu trả lời :) nó giúp tôi rất nhiều (để hiểu điều gì đang xảy ra với chương trình mà tôi đang làm) liên quan –

4

Hãy dùng thử. Logic này lặp đi lặp lại thông qua ngoại lệ chính và tất cả các nguyên nhân của nó, cho đến khi không còn nguyên nhân (cause == null) còn lại để xử lý. Bằng cách này bạn có thể tránh được 23 tin nhắn ... nữa. Tôi chưa thử nghiệm điều này, nhưng tôi tin rằng điều này sẽ làm việc cho bạn.

BTW - logWriter là một nhà văn được đệm. Bạn có thể muốn sử dụng System.out.print hoặc bất kỳ API ghi nhật ký nào khác.

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

Bạn có thể sử dụng 'Reader' để đọc qua đầu ra' printStackTrace' cho đến khi nó chạm _Caused by_ rồi lấy nguyên nhân và in dấu vết ngăn xếp của nó (tìm kiếm tiếp theo _Caused bởi _) ... và đệ quy lặp lại quá trình này cho đến khi có không còn dấu vết ngăn xếp nữa. Bằng cách đó bạn không phải xây dựng trình định dạng stacktrace tùy chỉnh của riêng bạn - bạn có thể sử dụng những gì đã có sẵn ':)' – ADTC

+0

Mã của bạn hoạt động tốt. Để gửi dấu vết đến system.out, tôi chỉ cần thêm 'BufferedWriter logWriter = new BufferedWriter (new OutputStreamWriter (System.out));' và ở cuối: 'logWriter.flush();' – Ben

Các vấn đề liên quan