如何在java中打印完整的堆栈跟踪

问题很简单,我想读取我捕获的exception的完整stacktrace 🙂

例:

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更多”)

问候 :)

答案很简单,那些行已经在堆栈跟踪:)

  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 } 

BalusC是对的。 请参阅: http : //java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html#printStackTrace()

尤其是:

注意包含字符“…”的行的存在。 这些行表明这个exception的堆栈跟踪的其余部分与由exception(“封闭”exception)引起的exception的堆栈跟踪底部的指定数目的帧匹配。 这种简写可以大大减less常见情况下的输出长度,在这种情况下,捕获的“引发exception”被捕获的同一个方法抛出的包装exception。

在你的例子中这意味着:

BasicDataSource.java行1136捕获了第1130行抛出的ClassNotFoundException ,并将其重新命名为SQLNestedException 。 因此, ClassNotFoundException的堆栈跟踪的其余部分与上面的SQLNestedException相匹配,并且stacktrace以更简洁的格式打印。

当外部exception(SQLNestedException)包装内部exception(ClassNotFoundError)时,它们位于同一个线程中,因此将共同的基础共享到其堆栈跟踪。

(23更多…)显示了内部exception的公共堆栈开始的位置,这也是外部exception抛出的地方。 所以,只要你看到(XX更多…),只要看看上面的exception,看看堆栈跟踪的其余部分。

如果您想以编程方式打印出没有通用跟踪的省略号的堆栈跟踪,那么您可以使用Throwable.getStackTrace()并自己打印出所有的元素。

试试这个。 这个逻辑遍历主exception和所有的原因,直到没有更多的原因( cause == null )被处理。 这样,你可以避免23更多…消息。 我还没有testing过,但我相信这应该为你工作。

顺便说一句 – logWriter是一个缓冲作家。 您可能想要使用System.out.print或任何其他日志loggingAPI。

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