Monday, December 9, 2019

missing parameter in Java event listener method signature produced confusing JSF server exception javax.el.PropertyNotFoundException: Target Unreachable, identifier 'wizardController' resolved to null

Documenting this because it was difficult to diagnose...

In my JSF/Primefaces application, I added a simple <p:inputText> component, with a "valueChangeListener" attribute for calling server-side Java code when the text field's value changes.  I created the Java method identified as the valueChangeListener, but forgot to add the parameter e.g., "ValueChangeEvent e" to the method signature.  When I opened the dialog containing the component, I received an exception like this on the server console:

SEVERE:   javax.el.PropertyNotFoundException: Target Unreachable, identifier 'wizardController' resolved to null
at com.sun.el.parser.AstValue.getTarget(AstValue.java:173)
at com.sun.el.parser.AstValue.invoke(AstValue.java:274)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.module.web.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.module.web.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at javax.faces.event.MethodExpressionValueChangeListener.processValueChange(MethodExpressionValueChangeListener.java:131)

This confused me because I thought the problem was in my client code, possibly an invalid EL expression that was resolving to null as stated in the exception.  After a lot of time looking at the client code, I realized I omitted the parameter in the method signature and with that fix the problem was resolved.

The client code looked like this:
                 <p:inputText id="#{viewName}QuantityInputText"
                             value="#{wizardController.dialogSpares.valueModelQuantity}"
                             required="true"
                             valueChangeListener="#{wizardController.dialogSpares.valueChangeListenerQuantity}">
The correct Java code is this:
        public void valueChangeListenerQuantity(ValueChangeEvent e) {
            setEnablement();
        }

But originally, I had not included the parameter:
        public void valueChangeListenerQuantity() {
            setEnablement();
        }

No comments: