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).



arjan tijms added a comment - 19/Mar/12 07:57 AM

After looking into it some more, I think something like the following in ActionSourceRule might do the trick:

final static class ActionListenerMapper2 extends Metadata {

    private final TagAttribute attr;

    public ActionListenerMapper2(TagAttribute attr) {
        this.attr = attr;
    }

    public void applyMetadata(FaceletContext ctx, Object instance) {
        
        ExpressionFactory expressionFactory = ctx.getExpressionFactory();

        MethodExpression methodExpressionOneArg = attr.getMethodExpression(
            ctx, null, ActionSourceRule.ACTION_LISTENER_SIG);
        
        MethodExpression methodExpressionZeroArg = 
                expressionFactory.createMethodExpression(
                    ctx, methodExpressionOneArg.getExpressionString(), 
                    Void.class, ActionSourceRule.ACTION_LISTENER_ZEROARG_SIG);            
        
        ((ActionSource2) instance)
                .addActionListener(new MethodExpressionActionListener(
                        methodExpressionOneArg, methodExpressionZeroArg));

    }

}

Note that I haven't tested this yet, but will do so later today.


arjan tijms added a comment - 19/Mar/12 10:49 PM

Patch for issue against Mojarra 2.2 trunk including test case


arjan tijms made changes - 19/Mar/12 10:49 PM
Field Original Value New Value
Attachment 2347.patch [ 49551 ]
arjan tijms added a comment - 19/Mar/12 10:52 PM

The proposed code indeed fixes the issue in my local test.

I ran the automated tests and no tests were failing because of this new change (a small handful of tests was already failing on my system before I applied the change, like scrumtesttoys).


rogerk added a comment - 20/Mar/12 02:07 PM

Thanks for the patch.
Fixed some minor problems in test (xhtml pages).


rogerk made changes - 20/Mar/12 02:07 PM
Attachment changebundle-2347.txt [ 49552 ]
rogerk added a comment - 20/Mar/12 02:10 PM

Committed to MOJARRA_2_1X_ROLLING branch:
Sending jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ActionSourceRule.java
Adding jsf-test/JAVASERVERFACES-2347
Adding jsf-test/JAVASERVERFACES-2347/build.xml
Adding jsf-test/JAVASERVERFACES-2347/htmlunit
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/pom.xml
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com/sun
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com/sun/faces
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com/sun/faces/systest
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com/sun/faces/systest/Issue2347TestCase.java
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/pom.xml
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/java
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/java/i_jsf_2347
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/java/i_jsf_2347/ActionListenerBean.java
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp/WEB-INF
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp/WEB-INF/web.xml
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp/actionlistener.xhtml
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp/include.xhtml
Sending jsf-test/build.xml
Transmitting file data ..........
Committed revision 9770.


rogerk added a comment - 20/Mar/12 03:11 PM

Committed to trunk:
Sending jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ActionSourceRule.java
Adding jsf-test/JAVASERVERFACES-2347
Adding jsf-test/JAVASERVERFACES-2347/build.xml
Adding jsf-test/JAVASERVERFACES-2347/htmlunit
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/pom.xml
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com/sun
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com/sun/faces
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com/sun/faces/systest
Adding jsf-test/JAVASERVERFACES-2347/htmlunit/src/main/java/com/sun/faces/systest/Issue2347TestCase.java
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/pom.xml
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/java
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/java/i_jsf_2347
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/java/i_jsf_2347/ActionListenerBean.java
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp/WEB-INF
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp/WEB-INF/web.xml
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp/actionlistener.xhtml
Adding jsf-test/JAVASERVERFACES-2347/i_jsf_2347/src/main/webapp/include.xhtml
Sending jsf-test/build.xml
Transmitting file data ..........
Committed revision 9771.


rogerk added a comment - 20/Mar/12 03:12 PM

Fix version


rogerk made changes - 20/Mar/12 03:12 PM
Affects Version/s 2.1.8 [ 15535 ]
Affects Version/s 2.2-m02 [ 15545 ]
Affects Version/s 2.1.7 [ 15380 ]
rogerk added a comment - 20/Mar/12 03:12 PM

Committed.


rogerk made changes - 20/Mar/12 03:12 PM
Status Open [ 1 ] Closed [ 6 ]
Resolution Fixed [ 1 ]
rogerk added a comment - 20/Mar/12 03:16 PM

fix version


rogerk made changes - 20/Mar/12 03:16 PM
Resolution Fixed [ 1 ]
Status Closed [ 6 ] Reopened [ 4 ]
rogerk added a comment - 20/Mar/12 03:16 PM

fix version


rogerk made changes - 20/Mar/12 03:16 PM
Fix Version/s 2.1.8 [ 15535 ]
Fix Version/s 2.2-m02 [ 15545 ]
Affects Version/s 2.1.7 [ 15380 ]
Affects Version/s 2.1.8 [ 15535 ]
Affects Version/s 2.2-m02 [ 15545 ]
rogerk added a comment - 20/Mar/12 03:16 PM

fix version


rogerk made changes - 20/Mar/12 03:16 PM
Status Reopened [ 4 ] Closed [ 6 ]
Resolution Fixed [ 1 ]
Manfred Riem made changes - 10/Jan/13 08:57 PM
Link This issue is related to JAVASERVERFACES-2681 [ JAVASERVERFACES-2681 ]