-->

Conflict between Omnifaces cdi param and JSF 2.3

2019-08-06 09:30发布

问题:

My web app encountered a problem with Omnifaces cdi param after upgrading the server from tomee plume 7 to tomee plume 8. I tested with a bare bone webapp and confirmed this.

My bean:

@javax.faces.view.ViewScoped
@javax.inject.Named
public class Bean2 implements java.io.Serializable {
  @javax.inject.Inject @org.omnifaces.cdi.Param
  private String tag;
  private String tag2;

  @javax.annotation.PostConstruct
  public void init() {
    if (getTag() == null || getTag().length()==0) {
        setTag2("None injected");
    }
    else 
        setTag2(getTag() + " injected");
    // Getters and setters

}

My JSF view:

<h:body>
    Tag: <h:outputText value="#{bean2.tag}" />
    <br/>
    <p:inputText readonly="true" value="#{bean2.tag2}"/>
</h:body>

I tried http://localhost:8080/test/inject2.jsf?tag=ABC and it works once only. Subsequent trials give:

java.lang.IllegalArgumentException: Unknown property tag of class com.mycompany.Bean2
at org.apache.bval.jsr.job.ValidateProperty$FindDescriptor.handleProperty(ValidateProperty.java:216)
at org.apache.bval.jsr.job.ValidateProperty$WalkGraph.handleProperty(ValidateProperty.java:312)
Caused by: javax.el.ELException: Error reading [tag] on type [com.mycompany.Bean2$$OwbNormalScopeProxy0]
at javax.el.BeanELResolver.getValue(BeanELResolver.java:98)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELR...

If I restart the server, it also works once only.

My environment Java: openjdk version "1.8.0_191", Primefaces 6.1, Omnifaces 2.6.9. I know not many people use TomEE but for info, TomEE plume 7 is based on Tomcat 8, Mojarra JSF 2.2 whereas TomEE plume 8 is based on Tomcat 9, Mojarra JSF 2.3. There are of course more differences but the test web app is so simple that what affects me should be Tomcat and JSF version only, with the SAME jar dropped in.

回答1:

This is not a bug in OmniFaces nor JSF nor CDI.

This is a bug in BVal (Apache's implementation of Bean Validation (JSR303)). The stack trace at least confirms that. It threw the exception from within the BVal classes.

The OmniFaces CDI @Param annotation has the feature that it automatically performs Bean Validation before injecting the value. This has always worked fine with older BVal versions and other BV implementations (e.g. Hibernate Validator).

Your best bet is to report this issue to BVal guys. In the mean while, you can work around this problem by disabling BV on the @Param.

@Inject @Param(disableBeanValidation=true)
private String tag;

I stumbled upon this issue myself in OmniFaces after upgrading the test server from TomEE 7.0.4 to TomEE 8.0.0-M2. Exactly the same problem as you've observed occurred during an IT. The fix was to disable the bean validation.

For the record, this is the full stack trace:

28-Apr-2019 12:18:37.479 SEVERE [http-nio-8080-exec-28] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [facesServlet] in context with path [/MultiViewsIT] threw exception [Unknown property secondPathParamAsInteger of class org.omnifaces.test.facesviews.multiviews.MultiViewsITBean] with root cause
java.lang.IllegalArgumentException: Unknown property secondPathParamAsInteger of class org.omnifaces.test.facesviews.multiviews.MultiViewsITBean
    at org.apache.bval.jsr.job.ValidateProperty$FindDescriptor.handleProperty(ValidateProperty.java:216)
    at org.apache.bval.jsr.job.ValidateProperty$WalkGraph.handleProperty(ValidateProperty.java:312)
    at org.apache.bval.jsr.util.PathNavigation$PathPosition.handleProperty(PathNavigation.java:324)
    at org.apache.bval.jsr.util.PathNavigation.parse(PathNavigation.java:218)
    at org.apache.bval.jsr.util.PathNavigation.navigateAndReturn(PathNavigation.java:176)
    at org.apache.bval.jsr.util.PathNavigation.navigate(PathNavigation.java:192)
    at org.apache.bval.jsr.job.ValidateProperty.<init>(ValidateProperty.java:490)
    at org.apache.bval.jsr.job.ValidateProperty.<init>(ValidateProperty.java:500)
    at org.apache.bval.jsr.job.ValidationJobFactory.validateValue(ValidationJobFactory.java:76)
    at org.apache.bval.jsr.ValidatorImpl.validateValue(ValidatorImpl.java:65)
    at org.apache.bval.jsr.CascadingPropertyValidator.validateValue(CascadingPropertyValidator.java:99)
    at org.omnifaces.util.Platform.validateBeanProperty(Platform.java:129)
    at org.omnifaces.cdi.param.ParamProducer.doBeanValidation(ParamProducer.java:403)
    at org.omnifaces.cdi.param.ParamProducer.validateBean(ParamProducer.java:252)
    at org.omnifaces.cdi.param.ParamProducer.validateValues(ParamProducer.java:223)
    at org.omnifaces.cdi.param.ParamProducer.produce(ParamProducer.java:103)
    at org.omnifaces.cdi.param.DynamicParamValueProducer.create(DynamicParamValueProducer.java:72)
    at org.apache.webbeans.component.third.ThirdpartyBeanImpl.create(ThirdpartyBeanImpl.java:97)
    at org.apache.webbeans.context.DependentContext.getInstance(DependentContext.java:68)
    at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:125)
    at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:813)
    at org.apache.webbeans.container.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:673)
    at org.apache.webbeans.inject.AbstractInjectable.inject(AbstractInjectable.java:100)
    at org.apache.webbeans.inject.InjectableField.doInjection(InjectableField.java:65)
    at org.apache.webbeans.portable.InjectionTargetImpl.injectFields(InjectionTargetImpl.java:227)
    at org.apache.webbeans.portable.InjectionTargetImpl.inject(InjectionTargetImpl.java:213)
    at org.apache.webbeans.portable.InjectionTargetImpl.inject(InjectionTargetImpl.java:203)
    at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:126)
    at org.apache.webbeans.component.ManagedBean.create(ManagedBean.java:66)
    at org.apache.webbeans.context.creational.BeanInstanceBag.create(BeanInstanceBag.java:76)
    at org.apache.webbeans.context.AbstractContext.getInstance(AbstractContext.java:159)
    at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:125)
    at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:101)
    at org.apache.webbeans.intercept.RequestScopedBeanInterceptorHandler.getContextualInstance(RequestScopedBeanInterceptorHandler.java:76)
    at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.get(NormalScopedBeanInterceptorHandler.java:71)
    at org.omnifaces.test.facesviews.multiviews.MultiViewsITBean$$OwbNormalScopeProxy0.getFirstPathParamAsString(org/omnifaces/test/facesviews/multiviews/MultiViewsITBean.java)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:94)
    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:62)
    at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:179)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190)
    at org.apache.webbeans.el22.WrappedValueExpression.getValue(WrappedValueExpression.java:68)
    at org.apache.myfaces.view.facelets.el.ELText$ELTextVariable.writeText(ELText.java:218)
    at org.apache.myfaces.view.facelets.compiler.TextInstruction.write(TextInstruction.java:45)
    at org.apache.myfaces.view.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:46)
    at org.apache.myfaces.view.facelets.compiler.UILeaf.encodeAll(UILeaf.java:491)
    at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:551)
    at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:551)
    at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1897)
    at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:315)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
    at org.omnifaces.viewhandler.OmniViewHandler.renderView(OmniViewHandler.java:121)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
    at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:117)
    at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:266)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:206)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:65)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLessToExtension(FacesViewsForwardingFilter.java:180)
    at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:137)
    at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:123)
    at org.omnifaces.facesviews.FacesViewsForwardingFilter.doFilter(FacesViewsForwardingFilter.java:84)
    at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.tomee.catalina.OpenEJBSecurityListener$RequestCapturer.invoke(OpenEJBSecurityListener.java:97)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)