Export to GitHub

primefaces - issue #4075

Facelet composition parameter not resolved by p:ajax


Posted on May 22, 2012 by Happy Rabbit

Parameter passed to ui:composition is not resolved by p:ajax

PrimeFaces version: 3.0, 3.1, 3.3 RC1?

What is the expected output? What do you see instead? The passed parameter should be resolved normally. Instead I get PropertyNotFoundException

Which JSF implementation with version are you using? Mojarra (bundled with Glassfish)

What is the version of your JSF implementation? 2.1.6

Which component libraries are you using in addition to PrimeFaces? none

Which application server or servlet container are you using? Glassfish 3.1.2

Test case:

page1.xhtml: <ui:composition xmlns="http://www.w3.org/1999/xhtml&quot; xmlns:ui="http://java.sun.com/jsf/facelets&quot; xmlns:h="http://java.sun.com/jsf/html&quot; xmlns:f="http://java.sun.com/jsf/core"&gt;

&lt;f:view contentType=&quot;text/html&quot;&gt;
    &lt;h:head&gt;&lt;title&gt;Test&lt;/title&gt;&lt;/h:head&gt;
    &lt;h:body&gt;
    &lt;h:form id=&quot;content&quot; prependId=&quot;false&quot;&gt;
      &lt;ui:include src=&quot;/WEB-INF/page2.xhtml&quot;&gt;
        &lt;ui:param name=&quot;controller&quot; value=&quot;#{testViewBean}&quot; /&gt;
      &lt;/ui:include&gt;               
    &lt;/h:form&gt;
    &lt;/h:body&gt;
&lt;/f:view&gt;

</ui:composition>

page2.xhtml: <ui:composition xmlns="http://www.w3.org/1999/xhtml&quot; xmlns:ui="http://java.sun.com/jsf/facelets&quot; xmlns:p="http://primefaces.org/ui"&gt; <p:inputText id="foo" value="#{controller.foo}"> <p:ajax event="blur" listener="#{controller.update}" /> </p:inputText> </ui:composition>

@Named @SessionScoped public class TestViewBean implements Serializable { private String foo; public String getFoo() { return foo; } public void setFoo(String foo) { this.foo = foo; }

public void update(AjaxBehaviorEvent e) { System.out.println("event handled"); } }

In the example above, the attribute "value" of p:inputText is resolved normally, as expected, but p:ajax throws PropertyNotFoundException when "blur" event happens (see the attached log).

Also, see the similar issue on RichFaces issue tracker, which was eventually resolved: https://issues.jboss.org/browse/RF-10781 (the only difference is that in my case I pass ValueExpression instead of MethodExpression).

I also asked this question on stackoverflow.com: http://stackoverflow.com/questions/10691636/facelet-tag-parameter-not-recognized-by-primefaces-pajax

Attachments

Comment #1

Posted on May 23, 2012 by Quick Bird

The patch below will fix this issue.

25a26

import javax.faces.view.facelets.FaceletContext; 43a45 FaceletContext fc = (FaceletContext) context.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY); 45c47

< createMethodExpression(elContext, listener.getExpressionString(), null, new Class[]{event.getClass()});

                    createMethodExpression(fc, listener.getExpressionString(), null, new Class[]{ event.getClass() });

Comment #2

Posted on May 23, 2012 by Quick Bird

sorry, forgot file name: AjaxBehaviorListenerImpl

Comment #3

Posted on May 29, 2012 by Swift Rhino

Does f:ajax work?

Comment #4

Posted on May 29, 2012 by Happy Rabbit

Does f:ajax work? Yes, it does.

Comment #5

Posted on Jun 26, 2012 by Swift Camel

Comment deleted

Comment #6

Posted on Jun 26, 2012 by Swift Camel

Reproduced on primefaces 3.3.1

The error comes from AjaxBehaviorListenerImpl.processAjaxBehavior which do not reconstruct/reuse correctly the variable mapper of the listener :

MethodExpression argListener = context.getApplication().getExpressionFactory().createMethodExpression(elContext, listener.getExpressionString(), null, new Class[]{event.getClass()}); argListener.invoke(elContext, new Object[]{event});

If the event listener has no parameter it works because "listener" has the correct variable mapper.

Comment #7

Posted on Jul 20, 2012 by Happy Hippo

The listner MethodExpression is build on TagHandler#apply with FacletesContext as ElContext. That's why the listener expression works well.

The new builded argListener MethodExpression in AjaxBehaviorListenerImpl.processAjaxBehavior doesn't have the FacletesContext anymore and so all Facelets variables like ui:param are lost.

Therefore I think it's needed to build all possible MethodExpressions for the AjaxBehavior in the TagHandler#apply like e.g. MyFaces does it in the f:ajax TagHandler.

Comment #8

Posted on Oct 29, 2012 by Swift Camel

You can find as attachment a patch and the source code modified

The patch modifies AjaxBehaviorListenerImpl : - I have added a second MethodExpression args (listenerWithArg) to its constructor
- processAjaxBehavior method first calls the original listener.invoke. If the method is not found it calls listenerWithArg.invoke

The patch modifies AjaxBehaviorHandler : - createAjaxBehavior constructs AjaxBehaviorListenerImpl with a second MethodHandler which takes a AjaxBehaviorEvent as an argument

Attachments

Comment #9

Posted on Oct 30, 2012 by Happy Rabbit

You gotta be kidding me! I opened this ticket half a year ago. 16 people starred it, some even attached their patches, and it's still in Review phase? I understand, I'm not a premium user, but it's clearly a bug. Way to go, PF team!

Comment #10

Posted on Oct 30, 2012 by Swift Rhino

This is common in open source projects, not only PrimeFaces related. There are priorities. We'll review this in the future, currently the team has no free time on this due to PRO user requests and regular workload of other projects, thanks for your understanding. If this is urgent, please consider PrimeFaces PRO.

Comment #11

Posted on Oct 31, 2012 by Swift Rhino

Set to review for 3.4.2 (release date next week) and 3.5.

Comment #12

Posted on Oct 31, 2012 by Swift Rhino

(No comment was entered for this change.)

Comment #13

Posted on Oct 31, 2012 by Swift Rhino

Fixed for 3.5 and 3.4.2.

Anton, I'd appreciate if you can understand the workload of ours, dealing with PrimeFaces PRO user requests to keep the business going, consulting, training and project development work plus on top of these trying to satisfy community users who has thousands of requests. This is common in any popular open source project, not just PrimeFaces. So we have priorities and work according to them. Hope you consider this and be more constructive in your future comments in issue tracker and forum.

Comment #14

Posted on Oct 31, 2012 by Massive Hippo

If I pull the 3.5 snapshot right now will I get this fix?

Comment #15

Posted on Oct 31, 2012 by Happy Rabbit

Sorry for being rude. I understand your workload and appreciate your efforts. I just thought that people who attached their patches deserved some attention. Because, even if they are not PRO users, they actually spent their time to fix the bug. I'll consider your notes on being more constructive next time.

Comment #16

Posted on Nov 8, 2012 by Massive Cat

this patch solved many of my problem (with input, selectOneRadio...) but do not solve case on a calendar with ajax event dateSelect

to reproduce: pass the ui_prm_bean as an ui param

// as in user guide 3.4 public void handleDateSelect(DateSelectEvent event) { Date date = event.getDate(); //Add facesmessage }

If i change the signature with param event as AjaxBehaviorEvent type, it's better, but event must be then casted to DateSelectEvent to get the date ...

Thanks

Comment #17

Posted on Nov 26, 2012 by Happy Bear

not resolved in 3.4.2 yet, same issue

Comment #18

Posted on Nov 27, 2012 by Happy Hippo

if you use the following method signature in the example above it should work.

public void handleDateSelect(ActionBehaviorEvent event) { DateSelectEvent dateSelectEvent = (DateSelectEvent)event); ... }

Using DateSelectEvent directly doesn't work with ui:param.

Comment #19

Posted on Dec 6, 2012 by Swift Rhino

Issue 4621 has been merged into this issue.

Comment #20

Posted on Dec 10, 2012 by Grumpy Monkey

There remains a problem with this for itemSelect event listeners for p:autocomplete tags in PF 3.4.2. You need to use the method signature workaround to get it working:

This works: public void onSelect(AjaxBehaviorEvent event) { Object selectedItem = ((SelectEvent) event).getObject(); ... }

This fails: public void onSelect(SelectEvent event) { ... }

javax.el.PropertyNotFoundException: Target Unreachable, identifier 'relationBean' resolved to null

/client/add.xhtml

/supplier/add.xhtml

/relation/form.xhtml

Comment #21

Posted on Dec 19, 2012 by Swift Rhino

Issue 4585 has been merged into this issue.

Comment #22

Posted on Jan 24, 2013 by Quick Horse

It looks that this issue still exists in 3.5.RC

Comment #23

Posted on Feb 4, 2013 by Happy Rhino

Still exists in current 3.5.RC1.

Comment #24

Posted on Feb 4, 2013 by Happy Hippo

The workaround using AjaxBehaviorEvent instead of the primefaces events and cast in the listener methode works.

Using primefaces event class directly in mehtode signature won't work. IMHO this couldn't be fixed easily because at this stage when the methode expression is built you don't know, which event was fired.

IMO the workaround described above is the only way at the moment.

Comment #25

Posted on May 12, 2013 by Helpful Hippo

The issue still exist in PF 3.5. I've not tested workarounds with cast of ActionBehaviorEvent, etc., but it's really annoying that we can not pass beans into ui:include via ui:param because they can not be resolved in p:ajax.

For now I use o:methodParam from OmniFaces to rescue the app. It works with o:methodParam when it's placed within included page.

Comment #26

Posted on Dec 4, 2014 by Happy Hippo

Still i in PF 5.1 :(

Comment #27

Posted on Jun 22, 2015 by Massive Camel

Still found on PF5.2, please reopen this!

Status: Fixed

Labels:
Priority-Medium Type-Defect TargetVersion-3.4.2 TargetVersion-3.5