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

时间:2011-01-31 11:13:43

标签: java java-ee-6 cdi jboss-weld jsr330

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

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

我希望有切换开关可以很容易地启用以下内容:

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

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

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

3 个答案:

答案 0 :(得分:9)

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

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

  

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

收听ProcessAnnotatedType - 活动

  

哪些豆类可供注射   哪个班级?

查询BeanManager。

  

是什么造成了给定的豆子不是   考虑以后?给定的罐子?

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

答案 1 :(得分:3)

我可以建议一些选择:

  • 降低记录阈值。我不知道Weld使用了什么日志框架,但您可以看到并配置,例如DEBUGINFO

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

  • 尝试使用不同的实现(如果没有绑定应用程序服务器) - 例如OpenWebBeans。它的异常消息可能更好

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

我可以确认Weld的异常消息令人失望。我没有使用Guice,但在Spring中它们非常非常有用。有了Weld,我不得不参考上面的第4点(打开规范)并验证所有先决条件。这是我最初的怀疑 - 即使规范看起来非常好,但实现方式也不会那么闪亮(起初至少)。但我想我会习惯这个。

答案 2 :(得分:3)

Weld使用Simple Logging for 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

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

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