2010-06-03 19 views
37

La pregunta es simple, quiero leer la StackTrace llena de una excepción que capturo :)cómo imprimir el StackTrace completa en java

ejemplo:

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 

(quiero leer el "... 23 más")

Saludos :)

+2

Gahhhh ... tantas carreras y procesos e invoca y ejecuta y dos ... http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns. html – naiad

+1

ver: http://stackoverflow.com/questions/1167888/howto-increase-lines-of-java-stack-trace-dump y http://stackoverflow.com/questions/1043378/print-full-call -stack-on-printstacktrace y http://stackoverflow.com/questions/437756/how-do-i-stop-stacktraces-truncating-in-logs para enumerar unos pocos – akf

+0

¡Hola! Mira http://people.inf.elte.hu/balopat/bug.html Te he generado, coloca el cursor sobre los círculos, espero que te ayude a entender qué significa '... 23 more' :) Básicamente las respuestas son verdaderas, esto es solo una ilustración. –

Respuesta

29

la respuesta es simple, esas líneas ya están en el 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) 

Básicamente, lo siguiente está sucediendo en BasicDataSource#createDataSource():

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

¿cómo? [....] – OscarRyz

+0

Bueno, ahora, cuando ha pasado un tiempo, leí que las respuestas eran muy simples, era un problema grave (o en este caso, falta el jar con el controlador de DB2. Está en: "Causado por: java.lang.ClassNotFoundException: COM.ibm.db2.jcc.DB2Driver" –

+1

Esto, para mí, no responde a la pregunta. Sí, esas líneas ya están en el seguimiento de la pila, ¡pero no están impresas! Cómo imprimirlos fue la pregunta, que no has respondido en absoluto! – plainOldNerd

24

BalusC es correcto. Ver aquí: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html#printStackTrace()

En particular:

nota la presencia de líneas que contienen los caracteres "...". Estas líneas indican que el resto de la traza pila para esta excepción coincide el número indicado de marcos de la parte inferior de la traza de la pila de la excepción que fue causada por este excepción (la "envolvente" excepción). Esta abreviatura puede reducir en gran medida la longitud de la salida en el caso común donde una excepción envuelta es lanzada desde el mismo método que la "excepción causal".

Lo que esto significa en su ejemplo es que:

BasicDataSource.java línea de 1136 llamó la ClassNotFoundException tirado en la línea 1130 y re-subió como un SQLNestedException. Por lo tanto, el resto de stacktrace para el ClassNotFoundException coincide con SQLNestedException anterior y stacktrace se imprime en este formato más conciso.

7

Cuando la excepción externa (SQLNestedException) ajusta la excepción interna (ClassNotFoundError) están en el mismo subproceso, y comparten una base común para su rastro de pila.

El (23 más ...) muestra dónde comienza esa pila común para la excepción interna, que es también el lugar donde se lanzó la excepción externa. Entonces, cada vez que vea (XX más ...), solo mire a la excepción anterior para ver el resto del rastreo de la pila.

Si desea imprimir mediante programación la stacktrace sin los puntos suspensivos de trazas comunes, puede usar Throwable.getStackTrace() e imprimir todos los elementos usted mismo.

+0

gracias a todos por las respuestas :) me ayuda mucho (para entender qué está pasando con el programa que estoy haciendo) respetos –

4

Pruebe esto. Esta lógica recorre la excepción principal y todas las causas de la misma, hasta que no haya más causa (cause == null) por procesar. De esta forma puede evitar el mensaje 23 más ... Todavía no he probado esto, pero creo que esto debería funcionar para usted.

BTW - logWriter es un escritor en búfer. Es posible que desee utilizar System.out.print o cualquier otra API de registro.

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

Puede usar un 'Reader' para leer la salida' printStackTrace' hasta que llegue a _Caused by_ luego obtener la causa e imprimir su traza de pila (buscando el siguiente _Caused by _) ... y recursivamente repetir este proceso hasta que haya un no hay más rastros de pila De esta manera, no tiene que crear su propio formateador de pila de datos personalizado: puede usar lo que ya está disponible ':)' – ADTC

+0

Su código funciona bien. Para enviar el rastreo a system.out, simplemente agrego 'BufferedWriter logWriter = new BufferedWriter (new OutputStreamWriter (System.out));' y al final: 'logWriter.flush();' – Ben

Cuestiones relacionadas