Issue Details (XML | Word | Printable)

Key: JAVASERVERFACES-2347
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: rogerk
Reporter: arjan tijms
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
javaserverfaces

No-args action listener can't be called if EL expression based on variable mapper

Created: 17/Mar/12 10:50 PM   Updated: 10/Jan/13 08:57 PM   Resolved: 20/Mar/12 03:16 PM
Component/s: None
Affects Version/s: 2.1.7
Fix Version/s: 2.1.8, 2.2.0-m02

Time Tracking:
Not Specified

File Attachments: 1. Text File 2347.patch (17 kB) 19/Mar/12 10:49 PM - arjan tijms
2. Zip Archive actionlistenertest.zip (2 kB) 17/Mar/12 10:50 PM - arjan tijms
3. Text File changebundle-2347.txt (32 kB) 20/Mar/12 02:07 PM - rogerk

Issue Links:
Related
 

Tags: el expression facelets
Participants: arjan tijms and rogerk


 Description  « Hide

When a no-args action listener is bound to e.g. a command button, it can't be called if the EL expression is dependent on a variable mapper in any Facelet context except the top level one (like includes and Facelet tags).

For instance, the following will fail:

top-level Facelet:

<h:form>
    <ui:include src="/include.xhtml" />
</h:form>

include.xhtml:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html">

    <ui:param name="test" value="#{actionListenerBean}" />

    <h:commandButton actionListener="#{test.listener}"
        value="invoke listener no param" />

</ui:composition>

actionListenerBean:

@ManagedBean
public class ActionListenerBean {
    public void listener() {	
    }
}

Clicking the button will throw the following exception:

 javax.el.PropertyNotFoundException: Target Unreachable, identifier 'test' resolved to null
	at org.apache.el.parser.AstValue.getTarget(AstValue.java:98)
	at org.apache.el.parser.AstValue.invoke(AstValue.java:244)
	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
	at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:153)

If the method expression binds to a method with an ActionEvent attribute everything works as expected.

As it appears, the problem has its root in the way how MethodExpressionActionListener is implemented. It copies the given method expression into a version without the ActionEvent attribute as follows:

public MethodExpressionActionListener(MethodExpression methodExpressionOneArg) {

        super();
        this.methodExpressionOneArg = methodExpressionOneArg;
        FacesContext context = FacesContext.getCurrentInstance();
        ELContext elContext = context.getELContext();
        this.methodExpressionZeroArg = context.getApplication().
                getExpressionFactory().createMethodExpression(elContext, 
                  methodExpressionOneArg.getExpressionString(), Void.class, 
                  ACTION_LISTENER_ZEROARG_SIG);

    }

The copy is made based on the expression string and the EL Context obtained from the TLS FacesContext, but this EL Context can not resolve the expression string. Is doesn't have the variable mapper of the EL Context in which the original expression was created.

Attached is a simple application that reproduces the problem (included ant file builds the .war in /dist).



No work has yet been logged on this issue.