对上下文和依赖关系注入进行故障诊断
对与 Java™ 平台企业修订版 (Java EE) 应用程序的上下文和依赖性注入 (CDI) 相关的错误进行故障诊断。
开始之前
关于此任务
使用 CDI 实现时,在应用程序部署期间或 CDI 与其他 Java EE 组件交互时,可能会遇到错误。您还可能会遇到生产者、拦截器和修饰符或诊断跟踪方面的问题。使用此任务可修正可能发生的错误。
过程
- 对应用程序部署问题进行故障诊断。 在应用程序部署时,容器必须验证应用程序中的每个注入点,并且仅该依赖关系的一个源能够满足。
避免故障: CDI 应用程序不支持热部署。为使更新可用,必须重新启动应用程序。gotcha
- 解决模糊依赖关系。
当容器将注入点类型或限定符解析为多个受管 bean、生产者方法或生产者字段时,会出现不明确的依赖性,或发生 javax.enterprise.inject.AmbiguousResolutionException 异常。
此异常显示正在处理的注入点,以及在类型安全解析过程结束时保留的候选 bean。除了单个 bean 之外,其他均为应用程序错误:
要解决错误,请完成以下其中一个操作:org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type OtherBean with qualifiers @Default at injection point [BackedAnnotatedField] @Inject private basic.injection.SimpleBean.bean at basic.injection.SimpleBean.bean(SimpleBean.java:0) Possible dependencies: - Managed bean [class basic.injection.OtherBean] with qualifiers [@Any @Default], - Producer Method [OtherBean] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces basic.injection.OtherBeanProducer.produceOtherBean()]
- 通过向注入点中添加限定符来消除注入点的歧义(如果需要,可向依赖关系的源中添加)。
- 如果需要,在针对注入不应考虑某些依赖性的情况下,使用 @Alternative 或 @Specializes 对其中一个上下文实例源进行注释。
- 解决不满意的依赖关系。 当匹配应用程序中注入点的对象没有相应源时,会发生无法满足的依赖性或 javax.enterprise.inject.UnsatisfiedResolutionException。API 类型的字段以及可选的限定符注释集合决定能够满足依赖关系的 bean 的集合。不可满足依赖关系的原因如下:
- 没有受管 bean 可以分配给注入点上的类型。
- 任何受管 bean 的生产者方法的返回类型都无法分配给注入点。
- 任何受管 bean 中的生产者字段的类型都无法分配给注入点。
- 其中一个上述方案有效,但是注入点上的限定符注释在 bean 或生产者中不存在。
注: 通过以下方法来解决错误:通过引入新的 bean、移除限定符或添加生产者字段或方法,从而使针对 API 类型和限定符的依赖关系可用。“Java 上下文和依赖关系注入”规范的第 5.2 部分详细描述了类型安全的解决方案。org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type OtherBean with qualifiers @British at injection point [BackedAnnotatedField] @Inject @British private basic.injection.SimpleBean.bean at basic.injection.SimpleBean.bean(SimpleBean.java:0) WELD-001475: The following beans match by type, but none have matching qualifiers: - Managed bean [class basic.injection.OtherBean] with qualifiers [@Any @Default], - Producer Method [OtherBean] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces basic.injection.OtherBeanProducer.produceOtherBean()]
- 解析钝化作用域依赖关系。 钝化是指移动内存辅助存储器中保存的空闲对象的操作。钝化作用域(例如,内置作用域 @SessionScoped 和 @ConversationScoped)要求使用此作用域的任何 bean 可以进行钝化操作。如果 bean 满足以下条件则具备钝化功能:是有状态会话 Bean;是任何其他受管 bean,并且既是序列化,又不含任何非序列化拦截器和修饰符。钝化作用域依赖关系的原因包括:
- 将现有 bean 的作用域更改为钝化作用域,例如,@SessionScoped 或 @ConversationScoped。
- 向现有具备钝化功能的 bean 中添加非序列化修饰符或拦截器。
- 确保有问题的 bean 为可序列化 bean。
- 确保 bean 的所有拦截器和修饰符均实现了序列化。
- 将受管 bean 的作用域更改为非钝化作用域。
- 解决模糊依赖关系。
- 对错误进行故障诊断,这些错误是由 CDI 与其他 Java EE 组件进行交互造成的。
@Inject 注释提供了附加类型的 Java EE 依赖关系注入。它与在 Java EE 5 中定义的注入的关系如下:
- 使用 @Inject 注释之外的注释的注入行为与先前发行版中的行为相同,且仅使用 @Inject 注释注入的依赖性为上下文实例,如 Java 上下文和依赖关系注入 (JSR299) 中所定义。
- 使用生产者字段和生产者方法可以为有限 CDI 功能(如类型安全注入)提供使用 @Resource、@PersistenceContext、@PersistenceUnit 和 @WebServiceRef 注释获取的 Java EE 依赖关系。
如果某个 Expression Language (EL) 引用了 JavaServer Pages (JSP) 和 JavaServer Faces (JSF) 组件的某个受管 bean,而您无法获取此引用的值,请考虑以下方法:- 确保 bean 类使用 @Named 注释进行注释,或使用定义 @Named 注释的构造型进行注释。
- 确保在将第一个字符转换为小写后,EL 表达式匹配 bean 类的类名。当您将 @Named 注释限定符用于值成员(例如,@Named("myName"))时,这会指定 bean 名称(特殊示例限定符),但不会更改此 bean 的 EL 名称。
对于 EJB 组件:- 可以使用 @Inject 和 @EJB 注释注入会话 bean。当您使用 @Inject 注释注入有状态会话 bean 时,会话 bean 可使用限定符利用类型安全注入,并可使其生命周期由其 CDI 作用域管理。
- 即使会话 bean 不是通过 @Inject 注释获取的,也可以进行拦截和装饰,这与其他受管 bean 不同。
对于 Web Service 组件:- 要根据 Web 服务描述语言 (WSDL) 文件开发 JAX-WS 客户机,请遵循“根据 WSDL 文件开发 JAX-WS 客户机”主题中概述的步骤。提示: 使用 wsimport 工具以生成可移植的 Java 工件,包括服务类。
- 如果要使用 @WebServiceRef 注释,将生成的服务类注入到 CDI 受管 bean,那么必须使用 -wsdllocation 参数调用 wsimport 工具。因此,生成的服务类可以移植到其他系统,因为服务类使用相对 URI 来引用 WSDL 文件,而不是使用绝对路径。
- 对生产者错误进行故障诊断。
- 生产者方法中的循环。 使用生产者方法时,每个参数被视为一个注入点,在注入点中,容器提供了依赖关系。因此,实现这些参数注入点的上下文对象的源不能是包含生产者方法的类。
- 复制生产者方法(在相同类中具有相同限定符的两个 @Produces 注释)。 如果类具有多个生产者字段,那么这些字段不可具有相同 API 类型和一组相同限定符,这是因为此类依赖性一定具有不明确性,将无法注入。
- 对拦截器和修饰符错误进行故障诊断。
避免故障: 在故障转移方案中,@Inject Validator 和 @Inject ValidatorFactory 不受支持。gotcha
- 在 beans.xml 文件中(或通过 @Priority)启用拦截器、修饰符启用拦截器以及修饰符。除了 EJB 会话 bean 之外,其他仅适用于 bean 的上下文实例。上下文实例是使用 @Inject 注释或通过在 BeanManager 接口上调用方法来获取的实例。
- 多个 bean 部署归档 (BDA) 中的拦截器和修饰符。如果拦截器或修饰符是通过 beans.xml 文件启用的,那么系统仅对该归档启用这些拦截器或修饰符。如果拦截器或修饰符是通过 @Priority启用的,那么系统对整个应用程序启用这些拦截器或修饰符。
- 使用诊断跟踪有助于确定发生错误的原因。
- 通过指定 JCDI=all:com.ibm.ws.cdi*=all:org.jboss.weld*=all 获取针对 CDI 的跟踪。
- 通过指定 EJBContainer=all:MetaData=all:Injection=all,获取针对与 Java EE 注入和 EJB 容器的交互的额外跟踪。
- 通过指定 all:com.ibm.ws.wswebcontainer*=all, 获取针对与 Web 的相关作用域和生命周期的交互的额外跟踪。
- 避免在受管 bean 的缺省构造函数中进行重量级操作。
给定受管 bean 的每个注入点都将收到一个新的客户机代理,除了使用代理时可能创建的实际 bean 实例之外,此代理还调用底层 bean 类的缺省构造函数。此外,由于依赖关系注入是在构造函数完成之后,因此构造函数无法使用注入的依赖关系。请查看 @PostConstruct 注释生命周期回调,以确定放置仅在底层实例中运行的后注入逻辑的位置。


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tweb_troubleshoot_cdi
文件名:tweb_troubleshoot_cdi.html