Как напечатать полную трассировку стека в Java - PullRequest
48 голосов
/ 04 июня 2010

Я хочу прочитать полную трассировку стека исключительной ситуации, которую я записал.

Например:

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», чтобы увидеть, откуда происходит исключение.

Ответы [ 4 ]

34 голосов
/ 04 июня 2010

Ответ прост, эти строки уже находятся в трассировке стека:)

 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
}
31 голосов
/ 04 июня 2010

BalusC верно. Смотрите здесь: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html#printStackTrace()

В частности:

Обратите внимание на наличие строк, содержащих персонажи "...". Эти строки указывают на то, что остаток от трассировка стека для этого исключения соответствует указанное количество кадров из нижняя часть следа стека исключение, которое было вызвано этим исключение («включающее» исключение). Эта стенография может значительно уменьшить длина выхода в общем случай, когда заключено исключение брошенный из того же метода, что и «Причинное исключение» пойман.

В вашем примере это означает, что:

BasicDataSource.java строка 1136 поймала ClassNotFoundException, брошенный на линию 1130, и ререйзила его как SQLNestedException. Следовательно, остаток от трассировки стека для ClassNotFoundException соответствует описанному выше исключению SQLNestedException, и трассировка стека печатается в этом более кратком формате.

11 голосов
/ 04 июня 2010

Когда внешнее исключение (SQLNestedException) переносит внутреннее исключение (ClassNotFoundError), они находятся в одном потоке и, таким образом, совместно используют общую базу для своей трассировки стека.

(еще 23 ...) показывает, где начинается этот общий стек для внутреннего исключения, которое также является местом, где было выброшено внешнее исключение. Поэтому всякий раз, когда вы видите (еще XX), просто посмотрите на исключение выше, чтобы увидеть остальную часть трассировки стека.

Если вы хотите программно распечатать трассировку стека без многоточия для общих трасс, то вы можете использовать Throwable.getStackTrace () и распечатать все элементы самостоятельно.

5 голосов
/ 04 июня 2010

Попробуйте это. Эта логика проходит через главное исключение и все его причины, пока не останется больше причины (cause == null) для обработки. Таким образом, вы можете избежать еще 23 ... сообщения. Я еще не проверял это, но я считаю, что это должно сработать для вас.

BTW - 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();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...