Weld/CDI最好的调试技巧是什么?

Tho*_*sen 22 java jsr330 cdi java-ee-6 jboss-weld

Java EE 6的一个优点是新的依赖注入框架 - 带有Weld参考实现的CDI - 它促使我们以一种与实现无关的方式开始内部迁移到JSR-330,其明确的目标是能够拥有核心jar被冻结,然后能够添加额外的罐子,提供新的模块替换核心jar中的功能.

我现在正在与Weld一起完成上述工作,坦率地说,封面背后有太多的魔力.无论是工作还是不工作,默认情况下它不会提供很多帮助,因此您可以调查错误并修复它.

我希望有切换开关可以轻松实现以下功能:

  • 扫描了哪些类路径条目以及在哪里?结果是什么?
  • 什么豆类可供注射哪一类?
  • 是什么导致给定的bean以后不被考虑?一个给定的罐子?

换句话说,我需要更详细地看待决策过程.出于某种原因,Guice并不需要这样做,也许是因为魔法少得多,也许是因为错误消息非常好.

您如何调试Weld应用程序,以及它有多大帮助?

jan*_*oth 9

简短回答:CDI没有专用的调试选项(因为规范不要求这样做),也没有专门的Weld调试选项.

答案:你可以自己做很多事情.熟悉CDI扩展机制,你会发现你可以轻松(真的!)编写自己的扩展来调试你所需的信息

扫描了哪些类路径条目以及在哪里?结果是什么?

听取ProcessAnnotatedType-Event

什么豆类可供注射哪一类?

查询BeanManager.

是什么导致给定的bean以后不被考虑?一个给定的罐子?

听取AfterBeanDiscovery-Event,看看你在BeanManager中得到了什么.基本上,以下方案使ManageBean不符合注入条件:

  • 好消息.你是否知道有人写过"放入这个并获得大量信息"的模块,而不是我必须先进行先决条件研究? (2认同)

huk*_*ley 5

Weld 使用 Java 简单日志记录 (sl4j)。如果您使用 Tomcat,我建议您添加sl4j-jdk14-x.x.x.jar到应用程序类路径并将以下行附加到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
Run Code Online (Sandbox Code Playgroud)

这将在控制台中生成大量调试信息,因此您最好选择特定的内容并注释掉其他行。

其他日志库(如 log4j)可以使用各自的配置文件并添加类似的级别进行配置。


Boz*_*zho 3

我可以建议一些选择:

  • 降低日志记录阈值。我不知道 Weld 使用什么日志框架,但你可以看到它并进行配置,DEBUG或者INFO

  • 获取源代码并在BeanManager实现中放置断点(BeanManagerImpl也许)。它是 CDI 中的主要类,处理几乎所有事情。

  • 尝试放置不同的实现(如果不受应用程序服务器绑定) - 例如OpenWebBeans. 它的异常消息可能会更好

  • 打开规范并阅读特定案例。通常情况下,您会错过给定的先决条件 - 例如注释必须具有特定的@Target,否则 CDI 不会处理它。

我可以确认 Weld 的异常消息相当令人失望。我没有使用过 Guice,但在 Spring 中它们提供的信息非常非常丰富。对于 Weld,我必须参考上面的第四点(打开规范)并验证所有先决条件。这是我最初的怀疑——尽管规范看起来非常好,但实现不会那么闪亮(至少一开始是这样)。但我想人们已经习惯了这一点。