Search code examples
jsfjakarta-eeelcoercionwildfly-8

Java EE 7, EL 3.0 spec. changes with respect to type coercion


So I've been away from Java EE for six months and I'm now back and migrating an application to Java EE 7 and I am noticing that JSR-341/ the EL 3.0 spec. contains changes in the section Type Conversion (now, section 1.23; formerly, section 1.18).

In section 1.23, the very first rule in all of the various types except String is that if X is null and Y is not a primitive return null. This is a much welcome change.

So my first question is: with regard to section 1.23.3 Coerce A to Number type N,

In EL 2.1:

If A is null or "", return 0.

In EL 3.0:

If A is null and N is not a primitive type, return null.
Else if A is null or "", return 0.

Is it now no longer necessary to set the system property org.apache.el.parser.COERCE_TO_ZERO=false?


Next, there are a couple of other changes that beg questions:

In the very first subsection, section 1.23.1 (formerly 1.18.1) To Coerce a Value X to Type Y, the rule for the general case is given. Now, a new bullet has been added (emphasis mine):

If X is null and Y is not a primitive type and also not a String, return null.

In section 1.23.2 Coerce A to String the first two bullets have been flipped around. They are now in the following order:

If A is null: return “”
Otherwise, if A is String: return A

It appears that whereas before a null String remained a null String after coercion, now a null String is coerced to an empty String. So my second question is: am I reading this correctly, that the String is now treated differently than the other kinds of objects with respect to coercion? If so, why?

Such a change seems counterintuitive because as we all know null has special meaning. Moreover, such a change is alarming because it can adversely affect the code that I'm migrating, which was was originally written against an older spec.

And, finally, my third question is: what about bean validation? Does this mean that now @NotNull annotations on Strings in backing beans are useless because coerced String values can never be null? I doubt it, but I'd like to know how the new changes all work together.


Solution

  • Is it now no longer necessary to set the system property org.apache.el.parser.COERCE_TO_ZERO=false?

    When you're using Apache EL parser (as used in among others Tomcat), that's correct. In other words, they have indeed finally implemented my own request on that.

    Given that you're using Wildfly, that should however not really be applicable in your particular case, as it doesn't use Apache EL, but just EL RI (like as in GlassFish) which had this part already right from the beginning on. This was just a minor oversight in the EL spec and Tomcat guys were just very picky on this (they had this part right too until Tomcat 6.0.16 and then mangled it in order to "comply" the oversight in the spec and after a lot of complaints they added this system property in 6.0.17 in order to be able to turn it off).


    am I reading this correctly, that the String is now treated differently than the other kinds of objects with respect to coercion?

    Nope. The ordering shouldn't matter, result would be the same all time. null is not a String anyway. The ordering has likely been changed for clarity and simplification of the implementation.

    In JSF perspective, this EL spec section only concerns writing results of EL expressions to HTML output (which is of String type), not updating model values with submitted/coerced/converted/validated values, as you seemed to expect. For that, you still need the following web.xml context parameter to let JSF interpret empty string submitted values as null:

    <context-param>
        <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
        <param-value>true</param-value>
    </context-param>
    

    This part has not changed as compared to JSF 2.0/2.1.