0

I ran into an issue when trying to work with a WAS 9 server which has MyFaces. My application works with Mojarra on tomcat.

A Minimal, Complete, and Verifiable example that can be tested in tomcat (please ignore anything to do with primefaces):

Mojarra : https://github.com/ravihariharan/primefaces-test MyFaces : https://github.com/ravihariharan/primefaces-test-myfaces

Reference files : TestNull.java, BaseBean.java , testnull.xhtml

Oracle Mojarra 2.2.15 vs Apache MyFaces issue 2.2.12

public class TestNull extends BaseBean {

private Boolean testNullRender; 
//This has not be been instantiated on purpose

public TestNull() {
    super();
}

@PostConstruct
public void postConstruct() {
   //HtmlPanelGroup panel = new HtmlPanelGroup();
   HtmlPanelGroup panel = (HtmlPanelGroup) FacesContext.getCurrentInstance().getApplication()
            .createComponent(HtmlPanelGroup.COMPONENT_TYPE);

    String valueExpression = "#{testNull.testNullRender}";
    panel.setValueExpression(PropertyConstants.RENDERED, createValueExpression(valueExpression, Boolean.class));

    addComponent("form:panelId", panel);
}

public Boolean getTestNullRender() {
    return testNullRender;
}

public void setTestNullRender(Boolean testNullRender) {
    this.testNullRender = testNullRender;
}
}

Error only in MyFaces :

java.lang.NullPointerException


phaseId=RENDER_RESPONSE(6)

Caused by:
java.lang.NullPointerException
 at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:1212)

- Stack Trace

java.lang.NullPointerException
    at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:1212)
    at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:504)
    at org.apache.myfaces.shared.renderkit.RendererUtils.renderChildren(RendererUtils.java:688)
    at org.apache.myfaces.shared.renderkit.html.HtmlGroupRendererBase.encodeEnd(HtmlGroupRendererBase.java:150)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:675)
    at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:555)
    at javax.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:551)
    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:1891)
    at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:313)
    at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:58)
    at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:116)
    at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:267)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:200)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)

Addition Update for MyFaces: Declarative ValueExpression working:

<h:panelGroup id="panelId0" rendered="#{testNull.testNullRender}">

Issue only with programmatic ValueExpression

String valueExpression = "#{testNull.testNullRender}";
        panel.setValueExpression(PropertyConstants.RENDERED, createValueExpression(valueExpression, Boolean.class));

        addComponent("form:panelId", panel);
Ravi
  • 391
  • 2
  • 18

1 Answers1

0

It should work fine if you change your testNullRender to a primitive. I'm not sure if Boolean as object is supported in the specs.

tandraschko
  • 2,291
  • 13
  • 13
  • I have been trying to figure the same since the two implementations of the specification Mojarra & MyFaces have different behavior and it seemed its a bug in MyFaces. – Ravi Nov 10 '17 at 13:09
  • I'm not sure if it's a bug. What does rendered=null mean? true and false are actually the only possible values IMO. – tandraschko Nov 10 '17 at 13:39
  • The Declarative ValueExpression works similar to Mojarra. The issue is only with Programmatic ValueExpression in MyFaces. – Ravi Nov 10 '17 at 13:53
  • This issue came to my notice because we use programmatic ui components for a dynamic questionnaire with a custom data structure. – Ravi Nov 10 '17 at 14:00
  • in the xhmtl should have also give the same error in MyFaces. But it works without any Exception. – Ravi Nov 10 '17 at 14:15
  • Did you try the following: https://stackoverflow.com/questions/16610655/why-should-i-use-createcomponent-instead-of-creating-the-instance-myself ? – tandraschko Nov 10 '17 at 16:54
  • Same error on using FacesContext.getCurrentInstance().getApplication() .createComponent(HtmlPanelGroup.COMPONENT_TYPE); – Ravi Nov 10 '17 at 17:15
  • I tried your example and as i already mentioned, it works fine if testNullRender is a primitive and can not return null. – tandraschko Nov 12 '17 at 12:08
  • I can see some change in the Expression Language. But since EL Spec 3.0 is part of tomcat i still could not figure why it would differ between Mojarra & MyFaces. – Ravi Nov 13 '17 at 02:36
  • Expression Language 2.1 1.18.5 Coerce A to Boolean If A is null or "", return false Otherwise, if A is a Boolean, return A Otherwise, if A is a String, and Boolean.valueOf(A) does not throw an exception, return it – Ravi Nov 13 '17 at 02:36
  • Expression Language 3.0 1.23.5 Coerce A to Boolean or boolean If A is null and the target type is not the primitive type boolean, return null If A is null or "", return false Otherwise, if A is a Boolean, return A Otherwise, if A is a String, and Boolean.valueOf(A) does not throw an exception, return it Otherwise, error – Ravi Nov 13 '17 at 02:37
  • since i had a custom data structured based on Object i got around by using String valueExpression = "#{testNull.testNullRender == true}"; which can work for Mojarra & MyFace. – Ravi Nov 13 '17 at 02:39