1. javaserverfaces-spec-public

Inconsistent handling of null/undeclared attributes, especially with nested components


    • Type: Improvement Improvement
    • Status: Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: 2.1, 2.2
    • Fix Version/s: None
    • Labels:
    • Environment:

      GF3 + JSF 2.1.26 or GF4 with JSF 2.2.3 with JDK7.0_45


      The origin is here:, but it's mainly worth reading the summary further down here.

      The reproducer is on .
      We have an outer component:

      <composite:attribute name="val1" type="java.lang.String"/>
      <composite:attribute name="val2" type="java.lang.String"/>
      <composite:attribute name="val3" type="java.lang.String" default="#{null}"/>
      <composite:attribute name="val4" type="java.lang.String" default="#{null}"/>
      <h:outputText value="Outer1: #{cc.attrs.val1 == null ? 'null' : (empty cc.attrs.val1 ? 'empty' : cc.attrs.val1)}" />
      <h:outputText value="Outer2: #{cc.attrs.val2 == null ? 'null' : (empty cc.attrs.val2 ? 'empty' : cc.attrs.val2)}" />
      <h:outputText value="Outer3: #{cc.attrs.val3 == null ? 'null' : (empty cc.attrs.val3 ? 'empty' : cc.attrs.val3)}" />
      <h:outputText value="Outer4: #{cc.attrs.val4 == null ? 'null' : (empty cc.attrs.val4 ? 'empty' : cc.attrs.val4)}" />
      <sr:test2 val1="#{cc.attrs.val1}" val2="#{cc.attrs.val2}" val3="#{cc.attrs.val3}" val4="#{cc.attrs.val4}" /> 

      And an inner component:

      	<composite:attribute name="val1" type="java.lang.String"/>
      	<composite:attribute name="val2" type="java.lang.String" default="#{null}"/>
      	<composite:attribute name="val3" type="java.lang.String"/>
      	<composite:attribute name="val4" type="java.lang.String" default="#{null}"/>
      		<h:outputText value="Inner1: #{cc.attrs.val1 == null ? 'null' : (empty cc.attrs.val1 ? 'empty' : cc.attrs.val1)}" />
      		<h:outputText value="Inner2: #{cc.attrs.val2 == null ? 'null' : (empty cc.attrs.val2 ? 'empty' : cc.attrs.val2)}" />
      		<h:outputText value="Inner3: #{cc.attrs.val3 == null ? 'null' : (empty cc.attrs.val3 ? 'empty' : cc.attrs.val3)}" />
      		<h:outputText value="Inner4: #{cc.attrs.val4 == null ? 'null' : (empty cc.attrs.val4 ? 'empty' : cc.attrs.val4)}" />

      And the actual page:

      <sr:test1 val1="AAA" val2="BBB" val3="CCC" val4="DDD"/>
      <sr:test1 val1="#{null}" val2="#{null}" val3="#{null}" val4="#{null}"/>
      <sr:test2  val1="DDD" val2="EEE" val3="FFF" val4="GGG"/>
      <sr:test2 val1="#{null}" val2="#{null}" val3="#{null}" val4="#{null}"/>

      When running one can notice a couple of odd things:

      1st case:
      On <sr:test1 .../>

      • feed <composite:attribute name="val1" type="java.lang.String"/> with null. Result: null
      • feed <composite:attribute name="val3" type="java.lang.String" default="# {null}"/> with null. Result: ""
        The developer, in the second line expects to get String var3 = null in the end. Instead he gets a real value.
        OK this is due to the mechanics of coertion but this is not consistent and imo should be fixed.

        2nd case:
        - Call the OUTER component dry <sr:test1/>. var1 isn't declared, so will be assumed null. In sr:test1 implementation is a call to <sr:test2 val1="#{cc.attrs.val1}"... The INNER(sr:test2) component is awaiting a String as val1 (<composite:attribute name="val1" type="java.lang.String"/>) and our non-declared attribute becomes "" (again) in the end! (see that lines 9 vs 13 of the output). In other words: feed a null to <composite:attribute name="val1" type="java.lang.String"/> directly, it stays null, feed it from a surrounding component, it becomes ""!

        3rd case:
        Calling directly the inner component <sr:test2/> and <sr:test2 val1="#{null}

        " val2="#

        {null}" val3="#{null}

        " val4="#


        "/> produce totally different results (see lines 29-32 vs 33-36 of the output). This is confusing for the developer and I'm not even sure this is a "feature".


        No work has yet been logged on this issue.


          • Assignee:
          • Votes:
            0 Vote for this issue
            1 Start watching this issue


            • Created: