<< Back to previous view

[JAVASERVERFACES-2229] Stange behaviour with the evaluation of the rendered-attribute Created: 15/Oct/11  Updated: 22/Apr/13  Resolved: 22/Apr/13

Status: Closed
Project: javaserverfaces
Component/s: None
Affects Version/s: 2.1.0
Fix Version/s: None

Type: Bug Priority: Trivial
Reporter: serdartosun Assignee: Unassigned
Resolution: Incomplete Votes: 1
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 7
Glassfish 3.1
Netbeans IDE
Enterprise Application


File Attachments: File TestDemo-ear-1.0-SNAPSHOT.ear    
Tags: rendered evaluation
Participants: Manfred Riem and serdartosun

 Description   

I have observed a strange behaviour with the evaluation of the rendered-attribute of components and it's child components.

I have the following xhtml page:

index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <h:panelGrid columns="2">
                <h:panelGroup >
                    <h:panelGroup rendered="#{testBeanOne.rendered}">
                        <h:dataTable value="#{testBeanOne.customer}" var="customer">
                            <h:column>
                                <f:facet name="header">
                                    <h:outputText value="Customer"/>
                                </f:facet>
                                <h:outputText value="#{customer.name}"/>
                            </h:column>
                        </h:dataTable>                        
                    </h:panelGroup>
                    <h:commandButton value="Render" actionListener="#{testBeanOne.buttonListener}"/>
                </h:panelGroup>

                <h:panelGroup>
                    <h:panelGroup rendered="#{testBeanTwo.rendered}">
                        <h:outputText value="#{testBeanTwo.text}"/>
                    </h:panelGroup>
                    <h:commandButton value="Render" actionListener="#{testBeanTwo.buttonListener}"/>
                </h:panelGroup>
            </h:panelGrid>
        </h:form>
    </h:body>
</html>

and the associated ManagedBeans

TestBeanOne.java
@ManagedBean
@SessionScoped
public class TestBeanOne {

    @EJB
    private CustomerFacadeLocal customerFacadeLocal = null;
    private boolean rendered = false;

    /** Creates a new instance of TestBeanOne */
    public TestBeanOne() {
    }

    public boolean isRendered() {
        return rendered;
    }

    public void setRendered(boolean rendered) {
        this.rendered = rendered;
    }

    public List<Customer> getCustomer() {
        return customerFacadeLocal.findAll();
    }

    public void buttonListener(ActionEvent event) {
        rendered = !rendered;
    }
}

and

TestBeanTwo.java
@ManagedBean
@SessionScoped
public class TestBeanTwo {

    private boolean rendered = false;
    private String text = "example text";

    /** Creates a new instance of TestBeanTwo */
    public TestBeanTwo() {
    }

    public String getText() {
        return text;
    }

    public boolean isRendered() {
        return rendered;
    }

    public void setRendered(boolean rendered) {
        this.rendered = rendered;
    }

    public void buttonListener(ActionEvent event) {
        rendered = !rendered;
    }
}

Now the problem is, the method TestBeanOne.getCustomer() gets called even TestBeanOne.rendered is set to false. So when the second "render"-button that is associated with TestBeanTwo gets pressed, TestBeanOne.getCustomer() gets called while TestBeanOne.rendered is false.

In return if TestBeanTwo.rendered is set to false and the first "render"-button that is associated with TestBeanOne gets pressed, TestBeanTwo.getText() doesn't get called. So there is an inconsistence behaviour while creating the DOM.

Methods get called while there respective xhtml component's or parent component's "rendered"-attribute is set to false. This behaviour causes unwanted effects and breaks the whole application.

For me occurs because I'm attempting to migrate a project from JSF 1.2/Glassfish 2.1 project to JSF 2.0/Glassfish 3.1 and this bug causes that the application doesn't work how it is supposed anymore.



 Comments   
Comment by Manfred Riem [ 24/Jan/13 02:26 PM ]

Can you please verify if it is still an issue on the latest 2.1 release?

Comment by Manfred Riem [ 22/Feb/13 02:10 PM ]

Lowering priority because of no response

Comment by Manfred Riem [ 23/Mar/13 12:08 AM ]

Lowering priority because of no response

Comment by Manfred Riem [ 22/Apr/13 01:17 PM ]

Closing because of inactivity





[EL_SPEC-11] Clarify how single variable evaluates to method Created: 08/Jan/13  Updated: 19/Mar/13  Resolved: 19/Mar/13

Status: Resolved
Project: el-spec
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: arjan tijms Assignee: Unassigned
Resolution: Fixed Votes: 2
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: methodexpression evaluation clarification
Participants: arjan tijms, beckchr and kchung

 Description   

Section 1.2.1.2 in the EL specification mentions that a method expression can consist of a single variable:

 
A method expression shares the same syntax as an lvalue. 
That is, it can only consist of either a single variable
(e.g. ${name}) or a property resolution on some object, 
via the . or [] operator (e.g. ${employee.name}).

As it appears, it's not entirely clear how such single variable should be evaluated.

In the reference implementation for example, we see that in this case a MethodExpressionImpl will reference an AstIdentifier, which will use the context's variable mapper to obtain a ValueExpression. The value is then obtained from this value expression, and it's expected to be a MethodExpression, which is then invoked.

This can be seen at http://java.net/projects/el-spec/sources/source-code/content/trunk/impl/src/main/java/com/sun/el/parser/AstIdentifier.java?rev=198 where the method getMethodExpression at line 198 demonstrates the "value expression wrapping a method expression" assumption. invoke at line 183 then shows this obtained method expression is simply invoked.

Comments on line 198 and 209 explicitly mention 2 cases:

case A: ValueExpression exists, getValue which must
be a MethodExpression

[...]

case B: evaluate the identity against the ELResolver, again, must be
a MethodExpression to be able to invoke

These cases however are not outlined in the specification. As a result, alternative EL implementations (like JUEL) have taken a completely different approach. In the case of JUEL, it also expects a ValueExpression, but then guessed that this value expression should be wrapping a Method. This on its turn leads to unexpected behavior and bugs such as reported here: http://code.google.com/p/omnifaces/issues/detail?id=100

In order to ensure portability between EL implementations, I would like to request this specific case to be clarified in the specification.



 Comments   
Comment by beckchr [ 08/Jan/13 07:35 PM ]

See also this issue from 2006: http://java.net/jira/browse/JSP_SPEC_PUBLIC-164

Comment by kchung [ 19/Mar/13 06:12 AM ]

What about adding the following clarification to 1.2.1.2

When a MethodExpression created from an EL expression of the form ${name} is invoked,

1. The identifier "name" is first evaluated.
a. If "name" is an EL variable, the ValueExpression associated with the variable is evaluated.
b. Else obtain the value resolved in the ELResolvers.
2. If the identifier evaluates to a MethodExpression, it is invoked and its result is returned.
3. Else error.

Comment by kchung [ 19/Mar/13 05:36 PM ]

Added a new section 1.5.4. in EL 3.0 spec to clarify the issue.

Comment by arjan tijms [ 19/Mar/13 05:45 PM ]

What about adding the following clarification to 1.2.1.2 [...]

It sounds okay to me, thanks!





Generated at Sat Apr 19 20:39:24 UTC 2014 using JIRA 4.0.2#472.