2

Empty form input fields bound to bean String type are received as empty strings ("") when the expected value is NULL.

This is an old problem that seems to get recreated with each version of Oracle EL or Apache EL or Tomcat.

@BalusC has addressed it many times. Empty String Madness, Tomcat 8 (and 9) coerce behaviour, null strings are incorrectly set as empty strings are a couple of examples.

I have tried all previous workarounds without success.

someform.xhtml

<h:form>
  <h:outputText value="Some Input: " />
  <p:inputText value="#{someBean.stringVariable}" />

  <p:commandButton id="search-button"
                    value="Search"
                    actionListener="#{someBean.doSearch}" />
</form>

SomeBean.java

private String stringVariable;
// Setter & Getter
public void doSearch()
{
    if(stringVariable == null)
    {
       System.out.println("Input is NULL");
    }
    else if(stringVariable.equals(""))
    {
       System.out.println("Input is EMPTY STRING");    
    }
}

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
    version="2.3">
        <application>
        <el-resolver>com.example.EmptyToNullStringELResolver</el-resolver>
    </application> 
    <application>
        <resource-handler>org.jepsar.primefaces.theme.jepsar.FontAwesomeResourceHandler</resource-handler>
        <resource-handler>org.omnifaces.resourcehandler.UnmappedResourceHandler</resource-handler>
    </application>  
    <application>
        <el-resolver>
           org.primefaces.application.exceptionhandler.PrimeExceptionHandlerELResolver
        </el-resolver>
    </application>
    <factory>
           <exception-handler-factory>
                 org.primefaces.application.exceptionhandler.PrimeExceptionHandlerFactory
           </exception-handler-factory>
    </factory> 
 </faces-config>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
  </context-param> 
  <context-param>     
    <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
    <param-value>com.sun.el.ExpressionFactoryImpl</param-value>   
  </context-param>
</web-app>

When I use the custom EmptyToNullStringELResolver method, a NPE is thrown.

java.lang.NullPointerException
    at org.apache.myfaces.shared.resource.ValueExpressionFilterInputStream.read(ValueExpressionFilterInputStream.java:130)
    at java.io.InputStream.read(InputStream.java:179)
    at java.nio.channels.Channels$ReadableByteChannelImpl.read(Channels.java:385)
    at org.omnifaces.util.Utils.stream(Utils.java:397)
    at org.omnifaces.resourcehandler.UnmappedResourceHandler.handleResourceRequest(UnmappedResourceHandler.java:176)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:196)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at ...

Dropping the most recent EL jar from Oracle into WEB/lib seems to have no effect. (javax.el-3.0.1-b11.jar)

Thank you, Ted S

Ted Spradley
  • 3,274
  • 3
  • 19
  • 23
  • 1
    The `EmptyToNullStringELResolver` and Oracle EL doesn't need to be done simultaneously. It's fine to do only one or the other. Can you please try that? Is the NPE still thrown and exactly the same on both approaches? The stack trace at least suggests that there's a `#{...}` expression somewhere in one of your CSS resources which actually resolved to `null`. – BalusC May 23 '19 at 18:01
  • A humble thank you @BalusC. Using only the EmptyToNullStringELResolver solved the String -> NULL problem. As far as the actual problem that I wasn't aware of, there was a missing image file referenced from one of my style sheets. What in the stack trace tipped you off to that please? And again, many thanks. – Ted Spradley May 23 '19 at 19:27
  • Just by reading the class/method names from bottom to top as usual .. Handle resource request .. stream .. read a value expression .. bang, something is null! – BalusC May 23 '19 at 20:15

1 Answers1

4

As per The Empty String Madness article, The EmptyToNullStringELResolver and Oracle EL doesn't need to be done simultaneously. For Tomcat 8.0.16 or newer the following is listed:

JF: add javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL=true context param.
ER: register EmptyToNullStringELResolver, or alternatively, just do UE.
UE: migrate/upgrade to Oracle EL implementation version 3.0.1-b05 or newer.

Note the "alternatively" word. Thus it's fine to do only one or the other.

As to the observed NullPointerException, it's thus happening when a ResourceHandler needs to stream a resource which could possibly contain EL expressions. This by default only happens on CSS resources in order to be able to support How to reference JSF image resource as CSS background image url. The ValueExpressionFilterInputStream represents MyFaces' internal class which is being used to evaluate EL expressions while reading an InputStream. However, it has apparently a bug whereby it doesn't expect EL expressions which return null instead of a concrete object. That problem is in turn actually unrelated to the solutions for "The Empty String Madness". It would have occurred nonetheless. You should at least scan your custom CSS files for EL expressions which incorrectly return null and fix them.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452