dev@javaserverfaces.java.net

RE: JAVASERVERFACES-3939

From: Xavier Dury <kalgon_at_hotmail.com>
Date: Fri, 15 Jan 2016 19:15:48 +0100

I was asking myself the same question about the session being created as a side-effect.
I came upon this warning for the viewScope when using prettyfaces on a transient view.
If I have the following rule in my pretty faces config (which is a very simple and typical use-case):
<url-mapping id="document"> <pattern value="/document/#{id}" /> <view-id value="/document.xhtml" /></url-mapping>
and a transient view document.xhtml like this:
<f:view transient="true"> <f:metadata> <f:viewParam name="id" value="#{myBean.id}" /> <f:viewAction action="#{myBean.loadDocument}" /> </f:metadata></f:view>
and myBean:
@ManagedBean_at_RequestScopedpublic class MyBean { public void setId(long id) {...} public void loadDocument() {...} public Document getDocument() {...}}
This will trigger the warning.
I don't think replacing #{id} with #{requestScope.id} in the prettyfaces configuration will work.
I don't know if there are other places in the code where UIViewRoot.getViewMap() is being called without considering that the current view may be transient.

Date: Fri, 15 Jan 2016 17:18:57 +0100
Subject: Re: JAVASERVERFACES-3939
From: arjan.tijms_at_gmail.com
To: dev_at_javaserverfaces.java.net

Hi,

On Fri, Jan 15, 2016 at 4:31 PM, Xavier Dury <kalgon_at_hotmail.com> wrote:


        String attribute = (String) property;

        FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);

        ExternalContext ec = facesContext.getExternalContext();

        if ((ec.getRequestMap().get(attribute)) != null) {

                ec.getRequestMap().put(attribute, val);

        } else if ((facesContext.getViewRoot()) != null && (facesContext.getViewRoot().getViewMap().get(attribute)) != null) {

                facesContext.getViewRoot().getViewMap().put(attribute, val);

        } else if ((ec.getSessionMap().get(attribute)) != null) {

                ec.getSessionMap().put(attribute, val);

        } else if ((ec.getApplicationMap().get(attribute)) != null) {

                ec.getApplicationMap().put(attribute, val);

        } else {

                // if the property doesn't exist in any of the scopes, put it in

                // request scope.

                ec.getRequestMap().put(attribute, val);

        }

This code seems indeed problematic. The view map is created only to check it, which not only causes an annoying warning, it also causes the creation of a session.
The same thing holds for the session map check. ec.getSessionMap().get(attribute) will create a session, even when this would not be needed.
For some types of applications, the needless creation of sessions is a serious problem. So regardless of the message being annoying or not, or clear or not, this session creation seems problematic to me.
The question is; how strict is the spec about mandating this?
Regardless, wouldn't changing the value expression mentioned in the issue to one that explicitly contains the scope work around a particular instance of this problem?
E.g.
ValueExpression ve = ef.createValueExpression(context.getELContext(), "#{requestScope.id}", Object.class);

instead of
ValueExpression ve = ef.createValueExpression(context.getELContext(), "#{id}", Object.class);

?