Después de varios años lidiando con toda suerte de excepciones en Java esta semana la oportunidad fue para java.lang.VerifyError. Luego de buscar soluciones muchas apuntaban a que debía recompilar el código que hacía uso de las classes modificadas pero esto no era posible para mi.

Imaginense este escenario: tienen que modificar un framework para adicionar una funcionalidad X que será util para una nueva aplicación, sin embargo las aplicaciones existentes que hacen uso del framework deben permanecer intactas ya que están certificadas y en ambientes productivos.

Luego de añadir la funcionalidad al framework las pruebas funcionan a la perfección en el ambiente de desarrollo pero al entregarlo a QA se instalan y todas las aplicaciones que dependen del framework lanzan ésta rara excepción.

En este punto lo que uno piensa es que quizás instalaron una versión incorrecta o que el ambiente esta corrupto, etc. Sin embargo después de cerciorarme desinstalando el framework e instalandolo por mi cuenta vi que efectivamente luego de instalar la nueva versión del framework surgia la excepción: java.lang.VerifyError.

Me resistía a pensar que la solución tuviera que ser recompilar las más de 30 aplicaciones que estaban haciendo uso del framework, ¡no podía ser cierto!. Pero en medio de todo la luz empezó a surgir, llegué a este artículo http://docs.oracle.com/javase/specs/jls/se5.0/html/binaryComp.html que habla sobre compatibilidad binaria. Éste sirvió para despejar mis dudas ya que apunta claramente al problema de la compatibilidad entre versiones sin que sea necesario recompilar las aplicaciones, no obstante aquí no pude encontrar el por qué se estaba generando la excepción.

Las pistas para obtener la respuesta las encontré en este artículo 3 reasons for java.lang.verfiyerror en el que se exponen los diferentes sabores de la excepción y el origen de ésta.

En mi caso especifico se trataba de un “Incompatible argument to function” que apuntaba a la firma de un método que no había cambiado. Sin embargo luego de revisar dentro de este método se hacía referencia a un objeto de otra classe que habia tenido varios cambios entre ellos que la nueva versión extendia de una clase diferente.

Al revisar el ambiente de QA pude observar que las classes de ese objeto no estaban actualizadas. Luego de actualizarlas la excepción desapareció sin necesidad de recompilar cada una de las aplicaciones que extendian del framework.

En conclusión si usted tiene un problema similar a este y puede recompilar las aplicaciones, hágalo es una via fácil y rápida para resolver este tipo de incidentes. Sin embargo si ud no tiene esa posibilidad es necesario que revise cuidadosamente el código dentro del método que esta causando la excepción, de esta forma podrá comparar entre un ambiente y otro si han cambiado las versiones e igualarlas.

Espero que esta información les ayude.

Hasta pronto.