bean java java-ee-6 cdi jboss-weld jsr330

java - bean - ¿Cuáles son los mejores trucos de depuración con Weld/CDI?



bean cdi (3)

Una de las bellezas con Java EE 6 es el nuevo marco de inyección de dependencias, CDI con la implementación de referencia de Weld, que nos ha llevado a comenzar a migrar internamente a JSR-330 de una manera independiente de la implementación, con el objetivo explícito de poder tener un el tarro del núcleo se congela, y luego se pueden agregar tarros adicionales que proporcionan nuevos módulos que reemplazan la funcionalidad en el tarro del núcleo.

Ahora estoy en el proceso de hacer el trabajo anterior con Weld, y para ser sincero, simplemente hay demasiada magia detrás de las portadas. O funciona o no, y no proporciona mucha ayuda por defecto en lo que sucede para que pueda investigar lo que está mal y solucionarlo.

Espero que haya interruptores para cambiar que puedan habilitar fácilmente cosas como:

  • ¿Qué entradas de classpath se escanean y dónde? ¿Cuál fue el resultado?
  • ¿Qué frijoles están disponibles para inyección para qué clase?
  • ¿Qué causó que un frijol dado no fuera considerado para más adelante? Un tarro dado?

En otras palabras, necesito ver el proceso de decisión con mucho más detalle. Por alguna razón, esto no es tan necesario con Guice, tal vez porque hay mucha menos magia, y quizás porque los mensajes de error son muy buenos.

¿Qué hace para depurar sus aplicaciones de soldadura y cuánto ayuda?


Puedo sugerir algunas opciones:

  • bajar el umbral de registro. No sé qué marco de registro utiliza Weld, pero puede ver eso y configurar, por ejemplo, DEBUG o INFO

  • obtenga el código fuente y coloque puntos de interrupción en la implementación de BeanManagerImpl (quizás BeanManagerImpl ). Es la clase principal en CDI y maneja casi todo.

  • Intente colocar una implementación diferente (si no está vinculada por el servidor de aplicaciones), por ejemplo, OpenWebBeans . Sus mensajes de excepción podrían ser mejores

  • Abra la especificación y lea sobre el caso particular. A menudo, es el caso de que no haya cumplido con una condición previa determinada; por ejemplo, una anotación debe tener un @Target específico, de lo contrario no es manejado por CDI.

Puedo confirmar que los mensajes de excepción de Weld son bastante decepcionantes. No he usado Guice, pero en primavera son muy, muy informativos. Con Weld tuve que referirme al cuarto punto anterior (abrió la especificación) y verificar todas las condiciones previas. Esta fue mi sospecha inicialmente: que aunque la especificación se ve muy bien, las implementaciones no serán tan brillantes (al menos al principio). Pero supongo que uno se acostumbra a esto.


Respuesta corta: no hay una opción de depuración dedicada para CDI (ya que la especificación no lo requiere), y no hay una opción de depuración dedicada para la soldadura.

Respuesta larga: hay muchas cosas que puedes hacer por tu cuenta. Familiarícese con el mecanismo de extensión de CDI , y descubrirá que puede (¡realmente!) Escribir fácilmente su propia extensión que depura la información requerida

¿Qué entradas de classpath se escanean y dónde? ¿Cuál fue el resultado?

Escuche el ProcessAnnotatedType -Event

¿Qué frijoles están disponibles para inyección para qué clase?

Consulta el BeanManager para eso.

¿Qué causó que un frijol dado no fuera considerado para más adelante? Un tarro dado?

Escuche el AfterBeanDiscovery -Event y vea lo que tiene en el BeanManager. Básicamente, los siguientes escenarios hacen que un ManageBean no sea elegible para inyección:


Weld utiliza Simple Logging para Java (sl4j). Si está utilizando Tomcat, le sugiero que agregue sl4j-jdk14-xxxjar a la ruta de clase de la aplicación y agregue las siguientes líneas a apache-tomcat-7.0.x/conf/logging.properties :

org.jboss.weld.Bootstrap.level = FINEST org.jboss.weld.Version.level = FINEST org.jboss.weld.Utilities.level = FINEST org.jboss.weld.Bean.level = FINEST org.jboss.weld.Servlet.level = FINEST org.jboss.weld.Reflection.level = FINEST org.jboss.weld.JSF.level = FINEST org.jboss.weld.Event.level = FINEST org.jboss.weld.Conversation.level = FINEST org.jboss.weld.Context.level = FINEST org.jboss.weld.El.level = FINEST org.jboss.weld.ClassLoading.level = FINEST

Esto generará una gran cantidad de depuración en la consola, por lo que es mejor seleccionar algo específico y comentar otras líneas.

Otras bibliotecas de registro (como log4j) se pueden configurar usando sus respectivos archivos de configuración y agregando niveles similares.