2009-06-24 10 views
5

Estoy tratando de solucionar un problema en mi aplicación Java que no arroja errores, sin excepciones y ni siquiera bloquea la aplicación (parece que la falla ocurre en un hilo separado).¿Cómo puedo depurar fallas silenciosas en aplicaciones Java?

El problema parece estar dentro de una llamada a una función de biblioteca (es JAXBContext.newInstance(String) si eso importa). El programa alcanzará la línea justo antes de la llamada, pero no la que está justo después. Mis bloques catch no se ingresan y el programa simplemente continúa ejecutándose.

El problema se produce al intentar presentar una respuesta XML a una solicitud web que entró a través de Struts. La solicitud se ha manejado y el código debe ordenar el objeto de respuesta. El cliente recibe una respuesta de inmediato (por lo que el código no parece colgarse), pero está vacío.

He establecido un punto de interrupción justo antes de la línea problemática, pero el depurador simplemente se ejecuta sobre él, no tengo ni idea por qué.

Estoy usando eclipse y la aplicación se ejecuta dentro de un contenedor OSGi (Apache Felix) que se inició con -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y. Desde dentro de Eclipse, utilizo la configuración de depuración para "Aplicación Java remota" para conectar el depurador.

¿Cuáles son las técnicas para llegar a ese problema?

+2

¿Estás seguro de que el IDE apunta al mismo código fuente que formó los binarios en el servidor? –

+0

Sí, todo está en mi máquina local y el contenedor OSGi ejecuta el código directamente desde el directorio de salida de mi IDE. –

+0

No estoy familiarizado con el contenedor OSGi, ¿lo hace, como JBoss, mueve los binarios desplegados a otro directorio? Intentaría hacer un cambio en tu código, un System.out.println o algo similar, luego asegúrate de que se ejecute para confirmar esto. Normalmente encuentro que el depurador omitiendo líneas de código indica que el IDE y el servidor no están sincronizados entre sí. –

Respuesta

0

Quizás dentro de la llamada haya un ciclo infitecito y por eso no hay más, pero esto podría no causar un bloqueo (a menos que se utilice la memoria en cada ciclo).

+1

No, no lo creo. El error ocurre al manejar una solicitud web que llega a través de Struts y el cliente obtiene un resultado (que está vacío) de inmediato. Entonces, la aplicación no se cuelga, salta del procesamiento. –

1

Si está seguro de que el problema está en alguna parte dentro de ese método, puede intentar mirar el JAXB source code.

EDIT:

Bueno, si se pone muy mal que pueda construir su propia copia privada con la depuración de la instrumentación. Espero que no tengas que recurrir a eso.

+0

Bueno, voy a intentarlo, pero sin conseguir que el depurador intervenga, podría estar teniendo dificultades. –

2

Puede intentar obtener un Thread Dump - que le dirá si algún método está bloqueando (por ejemplo, esperando la entrada). [Editar: volver a leer su pregunta original, obtener un volcado de hilo probablemente no ayude, ya que parece que en realidad nada está bloqueando. ¡Pero lo dejo aquí porque lo encuentro útil en muchas otras situaciones!]

Si crees que el error está ocurriendo en otro hilo, también puedes establecer UncaughtExceptionHandler para intentar atraparlo.

+0

Bloqueo: no, esta vez no. UncaughtExceptionHandler fue una buena idea, desafortunadamente tampoco captó nada. –

6

Probablemente una pregunta obvia, pero ¿estás seguro de que estás atrapando a Throwable? Una excepción no verificada fácilmente podría causar que el hilo en cuestión muera (suponiendo que nadie encima de ti en la pila de llamadas lo está capturando tampoco)

Como estás suspendiendo la VM en el inicio con tus argumentos de depuración, asumo que has confirmado que el depurador se está conectando correctamente. El hecho de que diga que el depurador se salta la llamada es muy sospechoso. ¿Eres capaz de golpear cualquier punto de quiebre en esta aplicación? ¿Qué tal en esta clase? ¿Qué tal en este hilo?

¿Cómo redujo la línea en cuestión sin el depurador? println/depuración en un archivo?

¿Se puede pegar un fragmento de código del método en cuestión?

Podría confirmar la teoría de que el hilo está muriendo creando un segundo hilo antes de que ocurra el problema y uniéndolo al hilo que cree que está muriendo.Luego, el método run() del segundo hilo se invocaría cuando el hilo en cuestión salga, y sabría que murió (pero aún no sabría por qué).

En respuesta a su pregunta general, cuando tengo un error en una aplicación de Java que no puedo reproducir en el depurador (lo que ocurre de vez en cuando por varias razones), modifico incrementalmente mi código con sysout printlns o salida a archivos. Si es necesario, también puedo modificar el código que mi código está invocando. Si no tiene el código fuente del código que invoca, puede probar uno de los muchos marcos BCI para insertar su código de bytes en los métodos en cuestión. Es un proceso tedioso, pero solo ocurre ocasionalmente.

+0

+1 No todos los Throwables son excepciones, y generalmente detectamos excepciones; es fácil que esto se nos escape. –

Cuestiones relacionadas