在较新版本的 JSF 中,@FacesValidator 和 @FacesConverter 中的 EJB 和 CDI 注入点无法通过 OmniFaces 工作
Posted
技术标签:
【中文标题】在较新版本的 JSF 中,@FacesValidator 和 @FacesConverter 中的 EJB 和 CDI 注入点无法通过 OmniFaces 工作【英文标题】:EJB and CDI inject points in @FacesValidator and @FacesConverter fail to work by means of OmniFaces in newer versions of JSF 【发布时间】:2015-06-10 01:38:45 【问题描述】:我正在使用,
Mojarra 2.3.0-m01 OmniFaces 2.0。 PrimeFaces 5.1 最终版 PrimeFaces 扩展 3.0.0 GlassFish 服务器 4.1以及其他 Java EE 工件。
@FacesValidator
中的注入点如下,
@FacesValidator(value="testValidator")
public class TestValidator implements Validator
@Inject
private DemoEJB ejb;
@Inject
private ManagedBean managedBean;
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
// Use the injected EJB and/or managed bean here.
那些注入点仍然是null
(我没有明确尝试注入 EJB,但它不应该像托管 bean 那样发生)。
由于上述 Mojarra 版本仍可作为快照使用,我尝试使用相同版本的 OmniFaces 2.0 将其降级到 2.2.10(或者也尝试使用 OmniFaces 2.1-SNAPSHOT - 在 Mojarra 2.2.10 上和 2.3.0-m01 替代)但无济于事。
当我将 Majarra 降级到 2.2.8-02 时,这很有效(交替使用 OmniFaces 1.8.1、2.0 和 2.1-SNAPSHOT 进行尝试)。我没有尝试其他 Mojarra 版本。
对于较新版本的 Mojarra,是否通过 OmniFaces(这反过来不需要任何附加依赖项和/或配置)将 @FacesValidator
和 @FacesConverter
候选作为 EJB 和 CDI 注入点的支持删除了?
我还没有在@FacesConverter
中明确尝试过,只是因为使用有缺陷的 NetBeans IDE 更改了这么多库,在 Windows 上运行速度也很慢,从黎明到黄昏花了一整天的时间。
编辑:
服务器产生以下 Weld 相关警告。
WARN: WELD-001700: Interceptor annotation class javax.ejb.PostActivate not found, interception based on it is not enabled
WARN: WELD-001700: Interceptor annotation class javax.ejb.PrePassivate not found, interception based on it is not enabled
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] private org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] public org.omnifaces.VetoAnnotatedTypeExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] public org.glassfish.jms.injection.JMSCDIExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] org.glassfish.sse.impl.ServerSentEventCdiExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>, BeanManager) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] private org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] private org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] public org.glassfish.jms.injection.JMSCDIExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] public org.glassfish.jms.injection.JMSCDIExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] public org.omnifaces.VetoAnnotatedTypeExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] org.glassfish.sse.impl.ServerSentEventCdiExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>, BeanManager) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] public org.glassfish.jms.injection.JMSCDIExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] org.glassfish.sse.impl.ServerSentEventCdiExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>, BeanManager) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] org.glassfish.sse.impl.ServerSentEventCdiExtension.processAnnotatedType(@Observes ProcessAnnotatedType<Object>, BeanManager) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-000411: Observer method [BackedAnnotatedMethod] private org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider.processAnnotatedType(@Observes ProcessAnnotatedType<Object>) receives events for all annotated types. Consider restricting events using @WithAnnotations or a generic type with bounds.
WARN: WELD-001473: javax.enterprise.inject.spi.Bean implementation com.sun.faces.cdi.ApplicationProducer@b15a70 declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. It won't be possible to inject this bean into a bean with a passivating scope (@SessionScoped, @ConversationScoped). This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.
WARN: WELD-001473: javax.enterprise.inject.spi.Bean implementation com.sun.faces.cdi.ApplicationMapProducer@db0450 declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. It won't be possible to inject this bean into a bean with a passivating scope (@SessionScoped, @ConversationScoped). This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.
WARN: WELD-001473: javax.enterprise.inject.spi.Bean implementation com.sun.faces.cdi.ViewMapProducer@1c55365 declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. It won't be possible to inject this bean into a bean with a passivating scope (@SessionScoped, @ConversationScoped). This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.
WARN: WELD-001473: javax.enterprise.inject.spi.Bean implementation com.sun.faces.cdi.ExternalContextProducer@14b1a6 declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. It won't be possible to inject this bean into a bean with a passivating scope (@SessionScoped, @ConversationScoped). This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.
WARN: WELD-001473: javax.enterprise.inject.spi.Bean implementation com.sun.faces.cdi.FacesContextProducer@1048acb declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. It won't be possible to inject this bean into a bean with a passivating scope (@SessionScoped, @ConversationScoped). This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.
WARN: WELD-001473: javax.enterprise.inject.spi.Bean implementation com.sun.faces.cdi.ViewProducer@275cfa declared a normal scope but does not implement javax.enterprise.inject.spi.PassivationCapable. It won't be possible to inject this bean into a bean with a passivating scope (@SessionScoped, @ConversationScoped). This can be fixed by assigning the Bean implementation a unique id by implementing the PassivationCapable interface.
【问题讨论】:
在 Tomcat 8.0.18 + Mojarra 2.3.0-m01(和 2.2.10)+ Weld 2.2.9 上为我工作。我现在手头没有 GF4.1,但它附带哪个 Weld 版本? GlassFish 4.1 中的 Weld 版本是 2.2.2,如 here 和 here 所述。尽管我不知道,是否有办法以编程方式获取此版本号。 GlassFish 4.1 也会发出一些与焊接相关的警告。我已将它们附加到问题中。 焊接版本记录为INFO: WELD-000900
。我将它降级到 Tomcat 的 2.2.2,但仍然无法重现它。应该稍后尝试 GF 4.1。这些警告不太可能相关。
确实在终端上记录为Info: WELD-000900: 2.2.2 (Final)
。
仅供参考,我启动并运行了 GF 4.1,将其捆绑的 Mojarra 2.2.7 升级到 2.2.10,并且我通过了 OmniFaces 2.1(快照)展示柜的测试。一切正常,包括@FacesConverter
中的 CDI/EJB 注入。换句话说,我仍然无法重现您的问题。
【参考方案1】:
这是由 Mojarra 2.2.9 中的更改引起的。它在 2.2.8 中运行良好。我在 GlassFish 4.1 和 WildFly 8.2 中都复制了它。在扫描了2.2.9 release notes 中列出的所有问题以及相关的变更包后,这似乎是issue 3552 向后移植到 JSF 2.2.x 的结果。他们在内部禁用了检查组件、行为、验证器和转换器的可注入性,这些组件、行为、验证器和转换器隐式地将它们注册为 CDI 托管 bean 候选者。换句话说,在 2.2.x 到 2.2.9 期间,Mojarra 无意中在上述工件中提供了“原生”@Inject
支持。
为了使@FacesConverter
和@FacesValidator
中的注入能够通过OmniFaces 正常工作,您需要添加一个空的/WEB-INF/beans.xml
或至少一个将bean-discovery-mode
设置为all
而不是annotated
。
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:weld="http://jboss.org/schema/weld/beans"
bean-discovery-mode="all"
>
<!-- ... -->
</beans>
它已经是默认值了,你也可以省略bean-discovery-mode
属性。
技术区别在于bean-discovery-mode="all"
会将所有 符合条件的类注册为 CDI 托管 bean,而 bean-discovery-mode="annotated"
仅将具有显式 CDI 范围注释的类(例如 @RequestScoped
)注册为 CDI 托管 bean ,因此对于 @FacesConverter
和 @FacesValidator
将失败。
【讨论】:
JSF 2.3 方法需要在类的注释中附加managed=true
属性来触发它。另见jdevelopment.nl/jsf-23
是否必须使用 bean-discovery-mode="all"。如果我用一些范围注释标记验证器,它不会工作吗? @RequestScoped 或 @Dependent 会起作用吗?
@guest 可悲的是,用 bean 定义注释标记 bean 也不起作用。您可以使用***.com/questions/17085717/… 中描述的步骤将您的 JSF 库降级为“支持注入”的 Mojarra 版本。因为 bean-discovery-mode="all" 很烂。以上是关于在较新版本的 JSF 中,@FacesValidator 和 @FacesConverter 中的 EJB 和 CDI 注入点无法通过 OmniFaces 工作的主要内容,如果未能解决你的问题,请参考以下文章
如何在较新版本的 libreoffice 中使用 unoconv
SVG sprite 图标背景位置在较新版本的 Chrome 中显示为关闭
如何在较新版本的 Delphi 中嵌入 YouTube 视频?
在较新版本的 Keras 中,LSTM 等效于 return_sequence = True