[JAVASERVERFACES_SPEC_PUBLIC-1107] Use VDLDoc tool for spec Facelets VDLDoc sections Created: 30/May/12  Updated: 26/Aug/15

Status: In Progress
Project: javaserverfaces-spec-public
Component/s: Documentation: Javadoc, TLDDoc, RenderkitDoc, PDF
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Critical
Reporter: Ed Burns Assignee: Ed Burns
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: 0 minutes
Time Spent: 9 hours, 5 minutes
Original Estimate: Not Specified

Issue Links:
Dependency
blocks JAVASERVERFACES_SPEC_PUBLIC-1106 Content of ui.taglib.xml Open

 Description   

Use output of JAVASERVERFACES-974 to generate Facelets VDLDoc.



 Comments   
Comment by Ed Burns [ 21/Feb/13 ]

Edward Burns wrote on 02/19/2013 08:38 AM:

EB> Also, until we upgrade the JSF build system away from tlddoc, and jsdoc
EB> (which doesn't support any kind of "bottom" option) and the home-grown
EB> renderkitdoc tool (which also doesn't support such a thing) the
EB> non-javadoc, non-pdf portions of the spec will not have this notice. If
EB> this is a problem, we need to allocate time to solve it.

>>>>> On Wed, 20 Feb 2013 20:39:08 -0800, Bill Shannon said:

B> We've lived with this for years and years so I wouldn't consider it high
B> priority, but please do add it to your list of issues to address.

Comment by Ed Burns [ 01/Aug/14 ]

Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.

Comment by Manfred Riem [ 01/Aug/14 ]

Setting priority to Minor

Comment by Manfred Riem [ 21/May/15 ]

Can you please isolate it to one ant target so the migration later on will be easier. Thanks!

Comment by Ed Burns [ 26/May/15 ]

M jsf-api/src/main/java/javax/faces/application/ApplicationConfigurationPopulator.java
M jsf-api/src/main/java/javax/faces/application/ProjectStage.java
M jsf-api/src/main/java/javax/faces/flow/FlowHandler.java
M jsf-api/src/main/java/javax/faces/flow/builder/NavigationCaseBuilder.java
M jsf-api/src/main/java/javax/faces/flow/builder/MethodCallBuilder.java
M jsf-api/src/main/java/javax/faces/flow/builder/SwitchCaseBuilder.java
M jsf-api/src/main/java/javax/faces/flow/builder/ReturnBuilder.java
M jsf-api/src/main/java/javax/faces/flow/builder/SwitchBuilder.java
M jsf-api/src/main/java/javax/faces/flow/builder/FlowCallBuilder.java
M jsf-api/src/main/java/javax/faces/flow/builder/NodeBuilder.java
M jsf-api/src/main/java/javax/faces/flow/builder/FlowBuilder.java
M jsf-api/src/main/java/javax/faces/view/BehaviorHolderAttachedObjectHandler.java
M jsf-api/src/main/java/javax/faces/view/AttachedObjectHandler.java
M jsf-api/src/main/java/javax/faces/view/facelets/AttributeHandler.java
M jsf-api/src/main/java/javax/faces/view/facelets/TagConfig.java
M jsf-api/src/main/java/javax/faces/view/facelets/FaceletsAttachedObjectHandler.java
M jsf-api/src/main/java/javax/faces/view/facelets/BehaviorConfig.java
M jsf-api/src/main/java/javax/faces/context/Flash.java

  • Fix javadoc errors and broken links.
    Sending jsf-api/src/main/java/javax/faces/application/ApplicationConfigurationPopulator.java
    Sending jsf-api/src/main/java/javax/faces/application/ProjectStage.java
    Sending jsf-api/src/main/java/javax/faces/context/Flash.java
    Sending jsf-api/src/main/java/javax/faces/flow/FlowHandler.java
    Sending jsf-api/src/main/java/javax/faces/flow/builder/FlowBuilder.java
    Sending jsf-api/src/main/java/javax/faces/flow/builder/FlowCallBuilder.java
    Sending jsf-api/src/main/java/javax/faces/flow/builder/MethodCallBuilder.java
    Sending jsf-api/src/main/java/javax/faces/flow/builder/NavigationCaseBuilder.java
    Sending jsf-api/src/main/java/javax/faces/flow/builder/NodeBuilder.java
    Sending jsf-api/src/main/java/javax/faces/flow/builder/ReturnBuilder.java
    Sending jsf-api/src/main/java/javax/faces/flow/builder/SwitchBuilder.java
    Sending jsf-api/src/main/java/javax/faces/flow/builder/SwitchCaseBuilder.java
    Sending jsf-api/src/main/java/javax/faces/view/AttachedObjectHandler.java
    Sending jsf-api/src/main/java/javax/faces/view/BehaviorHolderAttachedObjectHandler.java
    Sending jsf-api/src/main/java/javax/faces/view/facelets/AttributeHandler.java
    Sending jsf-api/src/main/java/javax/faces/view/facelets/BehaviorConfig.java
    Sending jsf-api/src/main/java/javax/faces/view/facelets/FaceletsAttachedObjectHandler.java
    Sending jsf-api/src/main/java/javax/faces/view/facelets/TagConfig.java
    Transmitting file data ..................
    Committed revision 14778.

In progress.

Comment by Ed Burns [ 22/Jul/15 ]

VDLDoc with -f -css showing -css isn't fully supported.





[JAVASERVERFACES_SPEC_PUBLIC-1359] Resolve views from dedicated folder Created: 02/Feb/15  Updated: 21/Aug/15

Status: In Progress
Project: javaserverfaces-spec-public
Component/s: Facelets/VDL
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Critical
Reporter: arjan tijms Assignee: Ed Burns
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to JAVASERVERFACES_SPEC_PUBLIC-1099 Resolve views by convention from dedi... Closed
is related to JAVASERVERFACES-3791 Implement JAVASERVERFACES_SPEC_PUBLIC... Open

 Description   

The Facelets VDL will by default try to resolve a view in the root of a web application or in META-INF/resources of a jar file (where the jar location automatically follows from using ServletContext#getResource)

In addition to this primary location I would like to propose loading views from a dedicated folder called "/views". This should be done in analogy to how contracts are loaded from "/contracts" and resources from "/resources", including the ability to let a user configure an alternative location.

The use case for this is letting the user easily configure a simple alternative location from where views are loaded and opening up more advanced processing by the runtime.

This more advanced processing is not part of this issue. This issue is strictly about providing a folder from which views (and only views) can be loaded.

Note that this issue is split-off from JAVASERVERFACES_SPEC_PUBLIC-1099, which asked about this folder but also asked about the advanced processing.



 Comments   
Comment by arjan tijms [ 03/Feb/15 ]

Sort of sub-issue of 1099





[JAVASERVERFACES_SPEC_PUBLIC-790] javax.faces.ViewState + PPR does not work out for cross form ppr cases Created: 06/May/10  Updated: 23/Jul/16

Status: In Progress
Project: javaserverfaces-spec-public
Component/s: Ajax/JavaScript
Affects Version/s: 2.0
Fix Version/s: 2.3

Type: Bug Priority: Critical
Reporter: werpu12 Assignee: balusc
Resolution: Unresolved Votes: 59
Labels: None
Remaining Estimate: 5 days
Time Spent: Not Specified
Original Estimate: 5 days
Environment:

Operating System: All
Platform: Macintosh


Attachments: Text File 790-js-workaround.txt     Text File changebundle.txt     Text File changebundle.txt     Java Source File ExtendedViewHandler.java    
Issue Links:
Duplicate
is duplicated by JAVASERVERFACES-3436 ViewScoped bean reconstructs when usi... Closed
Related
is related to JAVASERVERFACES_SPEC_PUBLIC-1093 The id attribute of javax.faces.ViewS... Open
is related to JAVASERVERFACES-1715 Missing ViewState during partial view... Closed
Issuezilla Id: 790
Status Whiteboard:

size_small importance_small


 Description   

Following problem

<h:form id="a">
    <h:commandButton action="#{TestBean.action}" value="submit"/>
</h:form>

<h:form id="b">
    <h:commandLink value="ajax ReRender" 
        onclick="jsf.ajax.request(this,event,{execute:'b a',render:'a'}); return false;"/>
</h:form> 

Cannot work out because, the viewstate is returned as separate viewstate block
(in both implementations the <update id="a"> does not pass the viewState in the
update block).

Now the specification says:

If an update element is found in the response with the identifier
javax.faces.ViewState:

<update id="javax.faces.ViewState">
   <![CDATA[...]]>
</update>

locate and update the submitting form's javax.faces.ViewState value with the
CDATA contents from the response.

Which means in this special case that the viewState for form a is lost.
Mojarra has fixed this to some degree by setting the viewstate if a direct form
render on a happens.

However if you do following:

<h:panelGroup id="myGroup">
    <h:form id="a">
        <h:commandButton action="#{TestBean.action}" value="submit"/>
    </h:form>
</h:panelGroup>

<h:form id="b">
    <h:commandLink value="ajax ReRender" 
        onclick="jsf.ajax.request(this,event,{execute:'b a',render:'myGroup'}); return false;"/>
</h:form> 

Mojarra also fails.

The problem here lies clearly with the spec, I am not sure why the viewstate is
only updated to the issuing form.

Either all forms must be updated or at least the forms which are processed both
within the execute and render parts.

I also opened a discussion on the open mailing list regarding this, since this is
a usecase which can happen quite often in a typical rich client scenario where a
lot of detachments can happen to satisfy ie6 and multiple forms are the norm if
you have floating frames.



 Comments   
Comment by Ed Burns [ 24/May/10 ]

Agree for inclusion in 2.0 Rev a

Comment by Ed Burns [ 24/May/10 ]

take ownership.

Comment by Ed Burns [ 27/May/10 ]

I agree we should update all forms. Move to 2.1.

Comment by Ed Burns [ 08/Jun/10 ]

triage

Comment by Ed Burns [ 24/Jun/10 ]

Change target milestone.

Comment by werpu12 [ 12/Jul/10 ]

Actually I personally think the only possible solution here is to offload this
to the server, instead of issuing <update id="javax.faces.ViewState"> we have to
extend the protocol here so that the client is notified which form and viewstate
element needs to be updated.
I am not sure if updating all forms automatically really resolves the issue,
because in a portlet scenario this does not work out, how about client side
state saving or even worse if someone introduces multiple viewroots
programmatically just as portlets do?

Comment by rogerk [ 27/Oct/10 ]

triage

Comment by frederickkaempfer [ 21/Sep/11 ]

The same problem occurs (in Mojarra 2.1.3) when the entire ViewRoot is replaced via ajax. In that case none of the forms get their view state updated. You need to submit a form at least twice in order to trigger the execution of the full JSF lifecycle. The first time only a new ViewState field is created in the submitted form.

At least all forms contained in the rendered section need to have their view state field updated. In the current implementation a ViewState field is only created if the render target is it self a form (not a parent of forms).

Updating all forms on the page is also a possibility though strictly speaking forms not contained in the <update/> section of the Ajax request are not part of the newly generated view state.

Possible duplicates of this bug I found so far:
http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1024
http://java.net/jira/browse/JAVASERVERFACES-2199

Comment by frederickkaempfer [ 22/Sep/11 ]

I have created a fix for the issue, which updates the ViewState field for forms which are children of the specified render targets.

Furthermore it handles the case where render="@all" is used. In this case all forms in the document will have their ViewState field updated. Previously this caused forms to loose their ViewState.

Note that this fix does not update all forms in the document, but only those which have been re-rendered (thus are part of the newly generated view on the server).

Comment by werpu12 [ 22/Sep/11 ]

Actually I have similar fixes for myfaces, I basically update all forms which have render targets in or forms which are part of a render target.
Additionally to that I added a update all config option which is outside of the spec.
But nevertheless.

But that is just a hack in my opinion. The root problem is in the protocol.
The protocol simply needs to deliver a list of form ids which need a viewstate update.
So I personally think the only viable long term solution to this problem simply is to update the protocol of jsf 2.2 in this regar ala <update id="javax.faces.ViewState" updateIds="id1 id2 id3">dkghsfkjgh</update> or for backwards compatibility reasons introduce an entirely new tag like <updateViewState id="...">....

Comment by rogerk [ 22/Sep/11 ]

Your workarounds are fine for now, but clearly this needs to be a spec change for the better.

Comment by frederickkaempfer [ 22/Sep/11 ]

If it was safe to assume that the ViewState does not change during a partial request the logic can be simplified by updating ALL forms in the document (not just render targets).

In Mojarra's ServerSideStateHelper (line 200) this assumption holds true, but I did not find anything in the spec enforcing this.

Additionally this would also take care of any Form dynamically added to the view or any render ids added via facesContext.getPartialViewContext().getRenderIds().add(...);

Right now only the "javax.faces.partial.render" argument is consulted which is indeed suboptimal.

I can change the workaround to simply update all forms in the page, which would also make it less of a "Hack". What do you think?

Comment by rogerk [ 22/Sep/11 ]

I was thinking along those same lines..
In which case we would not need to introduce a new response element as Werner mentioned.
It's been sometime since we looked at this - it has been discussed before.
Are there any portlet implications (namespace related) by doing this (that was brought up - but could be for a different issue)..

Comment by werpu12 [ 22/Sep/11 ]

Actually there are portlet implications, hence i stayed away from updating all forms automatically, but made it a config option you can turn on in myfaces.

The implication is that different portlets can host different forms under different viewroots and hence have different viewstates.
Now the main problem is, we dont have any viewroot information. So it comes down to following:
a) either send the viewstate info with an altered protocol i mentioned

  • safe since every form must have a unique id in the dom no double ids are allowed

b) add viewroot information and then update all forms under the corresponding viewroot - should be safe as well but is in my opinion not as clean as option a) and probably causes an alteration of the protocol as well (ala introduction of a viewroot element) or on the api side. I am not sure if we have a scenario where we have different viewstates under one viewroot though. I never really bothered to look deeper into this aspect of the jsf spec.

c) Try to move forward with the usual hacks - worst option of all

In my personal experience this multi form issue has been a huge issue for the users, I had about 5-10 requests on the myfaces mailinglist where users had problems and thought it was an issue of the implementation.

Comment by frederickkaempfer [ 23/Sep/11 ]

It's true that updating all forms won't work in any case where there are multiple viewroots involved. Anyhow I was hoping to find a solution that is usable even with the 2.1 and 2.0 spec versions, because this bug is not an enhancement, but currently breaks a couple of basic Ajax features in JSF. To summarize them quickly:

1. Specifying parents of forms as render targets.
2. Using the @all render target on any page with multiple forms.
3. Replacing the entire viewroot, for example via <h:commandLink action="myNavigationOutcome"><f:ajax/></h:commandLink>
4. Dynamically adding RenderIds that include forms in JSF Lifecycle with facesContext.getPartialViewContext().getRenderIds().add(...)

The workaround I provided should at least make 1-3 work again. Updating all forms in the document would make 1-4 work, but as you said will break Portlet compatibility.

There is another option to consider that does not require a protocol change:

Before the doUpdate function is called for any of the changes read the view state information at the end of the partial response document and save it in a variable in the jsf.ajax.response function. the viewstate can then be passed to any call of doUpdate function, which can then take care of creating view state fields where it is appropriate. This way we would not have to redundantly send the render ids, as they already provided as the <update> ids.

Comment by frederickkaempfer [ 23/Sep/11 ]

Here is a changebundle that updates the ViewState for each form element that is replaced during the ajax update.

I wonder if a Spec change is even necessary because: If a form is processed during an update it means that its ViewState field has to be updated (or created) as well. With this patch it is now done in the doUpdate function. On the other hand, if a form is not re-rendered there is no compelling reason to update its ViewState field, because if it had been changed on the server-side this would not be visible in the browser.

So following this logic, specifying the "updateIds" in a new protocol element will always replicate the render ids which are already contained in the <update> tags (or any of the forms contained in them, which can also be found using JavaScript, like it is done in the provided patch).

Do you think this is still too "hack"-ish?

Comment by werpu12 [ 23/Sep/11 ]

Unfortunately things are not that simple. I cannot speak for mojarra, but I assume it is similar, but myfaces has a meta information in the viewstate which also pinpoints to the viewid (and the state history as well) so if you do not update a second form even if you dont have a rerender there, you basically at a submit from that form can get a cannot find viewid once it drops out of the view history.

So we have two problems
a) update all forms automatically is prevented due to the fact that it breaks in a portlet environment

b) not updating not rendered forms might break the state history information of the viewstate not updated

So a pure javascript fixup will work and might work under normal non portlet circumstances (the simplest one probably is simply to update all forms for a normal webapp) but it will break in corner cases like portlet environments. Thats one of the reasons why I implemted about three fallback modes for this problem in myfaces. So that if even one fallback fails the user can switch to another one which might suite to his environment.

Comment by frederickkaempfer [ 23/Sep/11 ]

I think Mojarra does not even change the ViewState during partial requests.

Nevertheless I suppose there are two separate issues surfacing here that are remotely related. This patch should work in a Portlet scenario as well as the unpatched version and it fixes the 4 issues I mentioned earlier including the initial bug report. Contrary to updating all forms in the document, it doesn't make it any worse for the portlet scenario. But yes, it is a preliminary hack, if you consider the following change as the right way to handle the situation:

In your last comment you basically said that on each Ajax request all forms contained in a one ViewRoot have to be updated with new state information - at least in the case of MyFaces (it would work for Mojarra as well because the ViewState doesn't change):

  • If we are in a "normal" (non-portlet) environment with just one ViewRoot, this means updating all forms contained in the entire document.
  • If we are in a portlet environment it would mean updating all forms that are contained in the current ViewRoot.

So wouldn't the best course of action be your option b): make it possible to specify the view root element's id additionally in the partial response. If it is not specified or is set to a default value, update the entire document, if not only update forms contained in the viewroot element. This would also add the possibility to rerender a complete portlet with the special render target @all, which represents entire ViewRoot element. Sadly I don't know enough about the portlet spec to tell if this is a good idea and if this change is enough to support it properly.

Providing a list of update ids would then again be redundant, because the forms that need updating depend only on the ViewRoot that is currently - partly or in whole - redisplayed.

If this sounds like the right way to do it, then applying the changebundle will be counterproductive, because it is unnecessarily complex compared to updating all forms in the current ViewRoot. On the other hand it could even be backported to 2.0 or 2.1, it does not make things worse for portlets and it fixes the 4 critical bugs/problems i mentioned.

Comment by Ed Burns [ 23/Sep/11 ]

Thank you for excellent and clear analysis. Given my desire to include sketches for JAVASERVERFACES_SPEC_PUBLIC-730, JAVASERVERFACES_SPEC_PUBLIC-517, and JAVASERVERFACES_SPEC_PUBLIC-802, in next week's EDR of the spec, I'm going to defer this til after JavaOne.

Comment by codylerum [ 02/Nov/11 ]

This also is an issue with popup panels which often have their own form that when submitted rerenders content on the main page.

Since any forms on the main page did not participate in the submit they don't rerender with a viewstate and are unusable.

Comment by mdirkse [ 06/Dec/11 ]

Added a javascript workaround that fixes this issue and can be executed via the browser onLoad event handler. There are 2 versions: a plain JS one, and a jQuerified one. Tested and confirmed for Mojarra 2.1.2 (and jQuery 1.7.x).
Mad propz to frederickkaempfer for the original JS code.

Comment by werpu12 [ 06/Dec/11 ]

Sorry to crush some hopes here, but the posted solution is exactly the one I have in myfaces for the non portlet case (you can turn it on via a config param). And there it works, but it can only work in a non portlet environment, because there you have only one viewroot. So you can update all forms under document.

In a portlet environment you can have several viewroots under document with independend viewstates and independend forms. There the patch ultimately will break your portlet environment by applying wrong viewroots to other portlets. Thats because the which dom node is the viewroot info is simply missing on the client side and/or the protocol.

As I said before unless you have the viewroot info or you know which forms you update there is no way to resolve that issue for the portlet and non portlet case at the same time. The problem really is a problem of the protocol not the implementation.

Comment by rogerk [ 06/Dec/11 ]

I agree with Wevner's earlier assessment - that to handle the portlet case - multiple independent view root (eaxh with one or more forms) - we do need a new "server to client" message protocol that draws the association of which forms the view state should apply.

Comment by mdirkse [ 06/Dec/11 ]

werpu12 is right, the workaround I posted only works for the non-portlet case (and is only verified for mojarra 2.1.2)

Comment by sharath.naik [ 29/Dec/11 ]

Updating the MultiViewHandler's [ public void writeState(FacesContext context) throws IOException ] seems to fix the issue. The change made is to add the view state hidden field for forms, even when is a ajax request.

What is the purpose of not writing the view state if it is a partial request in this method?

Attaching the custom ViewHandler to override this method. would this be a fix that can be considered to be moved to MultiViewHandler?

Comment by frederickkaempfer [ 02/Jan/12 ]

@ sharath.naik: It's probably left out because the jsf ajax response already includes the view state information in an <update> tag, so the field can be created using JavaScript.

As I said earlier, the minimum a JSF implementation should do is update the view state information for all forms included in the render target list. I don't see how this creates any new problem in the portlet environment and that is what the latest changebundle I submitted does. Currently the algorithm detailed in the spec is not general enough and should be corrected.

A broader approach is to update all forms under the current view root. For that a protocol extension is necessary which tells the client which DOM element represents the view root. It would also enable scenarios where the whole view root is replaced (like @all and navigation) for the portlet environment. In my opinion for this a new spec enhancement should be issued.

Comment by codylerum [ 15/Feb/12 ]

Is the attached workaround meant to be called from the oncomplete of an ajax component or am I missing another way to trigger it?

Comment by frederickkaempfer [ 22/Feb/12 ]

@codylerum: it should be enough to execute the script once on a page load, after jsf.js is loaded of course.

Comment by Ed Burns [ 03/May/12 ]

TG> (First of all, javax.faces.ViewState should not be modified for Ajax
TG> updates using server-side state-saving, but this simple approach
TG> does not appear to be the current direction.)

Can you please elaborate more on what you mean by this? The issue
doesn't mention anything about Ajax specifically. Is this a separate
concern you are raising, Ted?

TG> We are a bit unclear on how the current implementation is intended
TG> to work, but expect that something like the following is necessary:

TG> When the request is submitted, call
TG> getElementsByName('javax.faces.ViewState') and store the list of IDs
TG> for all with equal value to that of the javax.faces.ViewState in the
TG> submitting form. In the case of future JSP inclusion or current
TG> Portlets, there will be javax.faces.ViewState fields not associated
TG> with the current view. They will have different values and are not
TG> included in the list.

TG> When the partial response is generated, it may contain rendered
TG> hidden inputs with name javax.faces.ViewState and unique IDs, but
TG> also contains the special case <update
TG> id="javax.faces.ViewState"><![CDATA[...]]></update>. The previously
TG> stored list of IDs are now all updated to use the new value. Any
TG> javax.faces.ViewState hidden fields that have been modified by the
TG> page update itself (potentially now having different IDs) have the
TG> correct value anyway because they were just updated.

These two comments are better suited to JAVASERVERFACES_SPEC_PUBLIC-790,
so I'll copy them there. Ted, can you please take a look at 790 and see
if you agree that your comments pertain more to that issue than this
one?

Comment by tedgoddard [ 07/May/12 ]

At least in the case of MyFaces, this complicates things considerably:

"Unfortunately things are not that simple. I cannot speak for mojarra, but I assume it is similar, but myfaces has a meta information in the viewstate which also pinpoints to the viewid (and the state history as well) so if you do not update a second form even if you dont have a rerender there, you basically at a submit from that form can get a cannot find viewid once it drops out of the view history."

It makes it necessary to update the ViewState key for every request. I was under the impression that a similar strategy was being considered for Mojarra.

In my above comments, I assume that the form Renderer would be modified to always write out the ViewState (even for partial rendering). Alternatively, the javax.faces.ViewState fields could be updated via two cases:

  • javax.faces.ViewState found in the current HTML document that match the submitting javax.faces.ViewState will be updated after the current response
  • javax.faces.ViewState found in the updated regions will be updated after the current response

This should handle portlet, servlet inclusion, and multiple form cases.

Comment by boogi [ 31/May/12 ]

Hi,
It says on fix version "2.2 Sprint 12" but it appears as unresolved on that sprint.
Do you a new estimation for the solution of this issue?

Comment by javaone9 [ 02/Nov/12 ]

I tried 2.1.14. it did not work.
I think this issue is urgent for any applications.

Comment by frederickkaempfer [ 18/Apr/13 ]

Please don't forget this issue for 2.2. It's one of the most annoying and frustrating aspects of the JSF Ajax experience. It would be a shame if the JSF community would have to wait another spec release -possibly another year- before this gets fixed.

tedgoddard made it very clear how to proceed with this issue in the previous comment.

Thanks a lot.

Comment by kfyten [ 25/Apr/13 ]

Roger/Ed - Just wanted to make it clear that this issue is currently blocking ICEfaces support for JSF 2.2. From a roadmap perspective it would be very helpful to us if this JIRA could be updated to reflect the current reality in terms of whether/when this issue may be resolved prior to 2.2 final release.

Thx.

Comment by rogerk [ 26/Apr/13 ]

Unfortunately I don't believe this made it into 2.2.

Comment by balusc [ 08/May/13 ]

This is really unfortunate.

In the meanwhile, developers can use this script to workaround the issue: http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#AutomaticallyFixMissingJSFViewStateAfterAjaxRendering

Comment by frederickkaempfer [ 08/May/13 ]

@balusc: I think that the workaround scripts have to be changed for 2.2, because the id of the ViewState field has been changed slightly. I didn't yet have time to look into it.

Comment by arjan tijms [ 08/May/13 ]

I think that the workaround scripts have to be changed for 2.2, because the id of the ViewState field has been changed slightly. I didn't yet have time to look into it.

They have changed indeed, see http://jdevelopment.nl/jsf-22/#220 and JAVASERVERFACES_SPEC_PUBLIC-220 for more details about this.

Comment by codylerum [ 08/May/13 ]

This is one of the larger pain points for developers utilizing ajax so it is very unfortunate that we are likely looking at years for resolution. Can anything be done at this point to speed that up?

Currently this issue has almost 2x the votes of the next closest issue.

Comment by swathireddy12 [ 22/Aug/13 ]

I am making use of JSF 1.2 version of jars (myfaces-api-1.2.9.jar ,myfaces-impl-1.2.9.jar,trinidad-api-1.2.13.jar,trinidad-impl-1.2.13.jar).
I am trying to retrieve the javax.faces.ViewState using the id attribute in a Javascript which works.

But i still don't see the id attribute in the loaded page
<input type="hidden" name="javax.faces.ViewState" value="!-14uywjgjai">

Could you please tell me if this is an issue with JSF 1.2 version as well?
Or once the page is rendered the id attribute associated with "javax.faces.ViewState" is not seen anymore.

Comment by werpu [ 22/Aug/13 ]

No this is a JSF 2.x issue only. This has nothing to do with JSF 1.2.

Comment by balusc [ 13/Jan/14 ]

This is one of the larger pain points for developers utilizing ajax so it is very unfortunate that we are likely looking at years for resolution. Can anything be done at this point to speed that up?

For exactly this reason, it has been added to OmniFaces 1.7: http://showcase.omnifaces.org/scripts/FixViewState

Comment by Ed Burns [ 01/Aug/14 ]

Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.

Comment by donvip [ 25/May/16 ]

Is this issue going to be fixed in JSF 2.3?

Comment by arjan tijms [ 25/May/16 ]

Is this issue going to be fixed in JSF 2.3?

I think we should definitely address this for 2.3. Thanks for the reminder!

Comment by balusc [ 30/May/16 ]

I'm currently looking at this.

As far as I see there are several solutions being proposed:

  1. Let JS blindly update/add view state of every single form in document - bad, might not work in portlet and might add noise to GET forms and/or non-JSF forms.
  2. Let JS update only missing view state of every single POST form in document - unclear if this works in portlets too.
  3. Let JS update only view states of all POST forms covered in ajax update targets - unclear if this works in portlets too.
  4. Always write view state to response - requires major spec change in ViewHandler#writeState(). I'd rather not do that.
  5. Include client IDs of all POST forms covered in ajax update targets in meta information of partial response.

I tend to implementing #3. Who can confirm if that will indeed work for portlets? Otherwise we'd better go for #5.

OmniFaces FixViewState by the way follows #2.

Comment by werpu [ 30/May/16 ]

The way I see it the ultimate fix on this issue, is a protocol change for the ajax response, we simply need the meta information there which viewstates in which forms need to be updated.
Everything else is a hack.

Comment by balusc [ 30/May/16 ]

Completely agree that. I updated the previous comment.

Comment by balusc [ 02/Jun/16 ]

Still no feedback from portlet guys.

I checked how MyFaces did it. They basically follows #2 with two little differences: it (incorrectly) updates GET forms too, and it skips everything when running in portlet environment.

Comment by werpu [ 02/Jun/16 ]

For multiform scenarios in no portlet environemnts I also added a config param which basically allows to override the default behavior and updates all forms reachable. This solved the multiform problem for many users since portlets are rather seldomly used.

Comment by werpu [ 02/Jun/16 ]

#2 simply turned out to be incorrect in multiform non portlet scenarios because the viewstate is kept over more than one form in the standard cases.
but also updating all forms is a no go for portlets, hence the config hack on my side.

Comment by balusc [ 02/Jun/16 ]

It's still not clear to me if #3 works for portlets. If it does, then #5 could be specified and implemented following same logic (i.e. update only JSF forms which are covered in ajax update targets).

Comment by donvip [ 02/Jun/16 ]

@balusc: thanks for the updates. The status on MyFaces is interesting, I didn't know they had implemented a workaround. Can you please tell me where I can find it? Is there an existing bug report/pull request concerning their incorrect implementation?

Comment by Neil Griffin [ 03/Jun/16 ]

@balusc, @werpu: Thank you for considering the portlet use-case. I think we can make #3 work in a portlet environment, but need to make sure that the javax.faces.ViewState hidden field values are only updated for forms that are associated with the portlet that invoked the XHR. (In other words, there could be other JSF portlets that are part of the HTML document that should not be touched by jsf.js, even though they share the same jsf.js resource).

In a portlet environment the UIViewRoot implements NamingContainer, thanks to javax.portlet.faces.component.PortletNamingContainerUIViewRoot

Because of this, the "id" attribute of forms is namespaced with the portlet id. For example, given this XHTML:

<h:form id="a">...</h:form>
<h:form id="b">...</h:form>

The following HTML would be rendered to the response:

<form id="Pluto_test_portlet_1__24955534_0_:a">...</form>
<form id="Pluto_test_portlet_1__24955534_0_:b">...</form>

If you consider the following XHR response:

<partial-response id="Pluto_test_portlet_1__24955534_0_">
  <changes>
    <update id="Pluto_test_portlet_1__24955534_0_:javax.faces.ViewState:0">
      <![CDATA[4617973942428228781:-2797886012162436717]]>
    </update>
  </changes>
</partial-response>

Then jsf.js could use the Pluto_test_portlet_1_24955534_0 namespace to make sure it only updates javax.faces.ViewState hidden fields in forms that contain that namespace in their "id" attribute.

As a side note, the portlet namespace is known to Mojarra as "namingContainerId" when it builds up mojarra.ab JavasScript. For more information, see AjaxBehaviorRenderer.java and jsf.js. Mojarra uses it to namespace XHR parameters such as javax.faces.partial.ajax in a portlet environment that requires strict parameter namespacing. The XHR parameter namespacing feature is unique to Mojarra – it has not yet been contributed to MyFaces.

Comment by balusc [ 06/Jun/16 ]

OK, I will propose the following API changes for JSF 2.3:

1. PartialResponseWriter#startDocument(): if UIViewRoot is available, then write UIViewRoot#getContainerClientId() as value of the id attribute of the <partial-response> element. Both Mojarra and MyFaces already implement this (although currently unspecified). In Mojarra's jsf.js, this value must replace/substitute the Mojarra-specific namingContainerId variable (which however appears to be already partially prepared for this, given the presence of a partialResponseId variable in doUpdate function which is totally unused). Portlets can then interpret this value as their parameter namespace (this is exactly what the Mojarra-specific namingContainerId did).

2. Correct an incorrect statement in the javadoc of ViewHandler#writeState() - it currently says that the <update> for javax.faces.ViewState is written into Ajax response during UIViewRoot#encodeEnd(). But this is untrue, in both Mojarra and MyFaces it actually takes place during PartialViewContext#processPartial(). I'll leave the reasoning for this deviation in the middle as this appears to be an oversight. Although I personally find that it makes more sense if it takes place during PartialResponseWriter#endDocument.

3. Update PartialViewContext#processPartial() to specify that during render response phase, the <update> for javax.faces.ViewState will be written, along with id attribute of exactly UIViewRoot#getContainerClientId() + UINamingContainer#getSeparatorCharacter() + ResponseStateManager#VIEW_STATE_PARAM. Currently, both Mojarra and MyFaces already implement this with one minor difference: an incremental counter identifying the form is being suffixed, this is now unnecessary.

4. Update the JSF 2.2 section (orange) of jsf.ajax.response jsdoc to remove <UNIQUE_PER_VIEW_NUMBER> altogether as below (changes in bold, strikeout means removal):

If an <update> element is found in the response with an identifier containing javax.faces.ViewState:

<update id="<VIEW_ROOT_CONTAINER_CLIENT_ID><SEP>javax.faces.ViewState">
   <![CDATA[...]]>
</update>

locate and update the submitting form's javax.faces.ViewState value with the CDATA contents from the response. <SEP>: is the currently configured UINamingContainer.getSeparatorChar(). <VIEW_ROOT_CONTAINER_CLIENT_ID> is the return from UIViewRoot.getContainerClientId() on the view from whence this state originated. <UNIQUE_PER_VIEW_NUMBER> is a number that must be unique within this view, but must not be included in the view state. This requirement is simply to satisfy XML correctness in parity with what is done in the corresponding non-partial JSF view. Locate and update the javax.faces.ViewState value for all forms specified covered in the render target list whose ID starts with the same <VIEW_ROOT_CONTAINER_CLIENT_ID> value.

The <UNIQUE_PER_VIEW_NUMBER> has no value in the API

@werpu: what do you think?
@Neil: is this acceptable for portlets?

Comment by Neil Griffin [ 06/Jun/16 ]

@balusc: Thank you for taking the time to propose these changes. Before I comment on your changes, I would like to make you aware of some portlet incompatibilities at are related to javax.faces.ViewState. When you get an opportunity, please read the class-level JavaDoc in ResponseWriterBridgeImpl.java and let me know if it might be appropriate to fix these incompatibilities for JSF 2.3. Thank you.

Comment by balusc [ 07/Jun/16 ]

I gather you're talking about limitation #3 in that javadoc? This should already be solved since JSF 2.2 where the javax.faces.ViewState hidden input field ID became namespaced with container client ID.

Comment by Neil Griffin [ 10/Jun/16 ]

@balusc: I'm referring mainly to #2 and #3 in the class-level JavaDoc in ResponseWriterBridgeImpl.java.

#2 is a workaround for the code in jsf.js that interprets <update id="javax.faces.ViewRoot">...</update> to mean replacing the <body>...</body> of the HTML document. I just created JAVASERVERFACES_SPEC_PUBLIC-1421 in order to see if the JSF EG would consider fixing jsf.js – it might be that the EG decides that this is a bridge concern and that the workaround should become a bridge requirement in JSR 378.

#3 is a workaround that causes the javax.faces.ViewState hidden field to always be rendered before the closing </form> tag when a partial-response is being written. It works around the code in jsf.js that attempts to add the hidden field to the DOM which fails in a portlet environment. This problem happens when a navigation-rule executes during an XHR. Specifically, the form that was submitted via f:ajax is no longer part of the DOM, since the entire portlet <div>...</div> section was replaced due to navigation to a different viewId. I suppose that the appropriateness of this workaround might be determined by the outcome of JAVASERVERFACES_SPEC_PUBLIC-1421.

Since this is all somewhat off-topic, I will provide feedback on your proposed API changes in a follow-up comment.

Comment by Neil Griffin [ 11/Jun/16 ]

@balusc: Your proposed API changes look good. However, should jsf.js need to add a javax.faces.ViewState hidden field to the DOM on-the-fly, the value of the name attribute should be prefixed by the namingContainerId. Looks like there is a bug in jsf.js in this regard. If you have time in your schedule, it would be great if you could fix the bug as part of your prototype work. Thanks, Neil.

Comment by balusc [ 11/Jun/16 ]

#2 is unrelated to the current issue. It's good you created issue 1421 on this.

I will keep the field name bug in mind. I only think it should be prefixed at the moment ajax request is to be sent, as done for all other params, not at the line you pointed out.

Comment by Neil Griffin [ 13/Jun/16 ]

That's fine to prepend the namespace at the time the request is sent. At first glance it looked like a bug to me because the bridge causes the namespace to be prepended when a component is rendered to the response.

Comment by Neil Griffin [ 14/Jun/16 ]

@balusc: Regarding the lines I mentioned in jsf.js – after the element is added to the DOM dynamically, then if the form is subsequently submitted without f:ajax (full-page postback) then the lack of a prepended namespace would be a problem.

Comment by balusc [ 17/Jun/16 ]

I see, will keep that in mind.

Comment by balusc [ 20/Jun/16 ]

Pushed: https://java.net/projects/mojarra/sources/git/revision/ff26c4dccafd50d22757ce8562230e31f9768033

@Neil: please let me know if that works for portlets as well and you could further reduce current workarounds in portlet side. FYI: the initial Mojarra implementation incorrectly omitted namingcontainer separator character from namespace prefix in ajax specific parameters. I have fixed that as well (and renamed Mojarra-specific RequestParameterMap#getNamingContainerId() to RequestParameterMap#getNamingContainerPrefix(), just in case you were relying on it).

@werpu: please let me know if the JSF/JS API changes are clear enough for MyFaces. Here's a summary:

ViewHandler#writeState(FacesContext)

@@ -737,8 +737,9 @@ public abstract class ViewHandler {
      * <code>Ajax</code> requests, the state is obtained by calling
      * {@link StateManager#getViewState}
      * and then written into the <code>Ajax</code> response during final
-     * encoding 
-     * ({@link javax.faces.component.UIViewRoot#encodeEnd}. 
+     * encoding <span class="changed_modified_2_3">
+     * ({@link javax.faces.context.PartialViewContext#processPartial(javax.faces.event.PhaseId)})
+     * </span>.
      * </p>
      *
      * @param context {@link FacesContext} for the current request

PartialViewContext#processPartial(PhaseId)

@@ -314,6 +317,17 @@ public abstract class PartialViewContext {
      * <code>Collection</code> returned from {@link #getExecuteIds} 
      * and {@link #getRenderIds} will be processed.</p>  
      *
+     * <p class="changed_added_2_3">When the indicated <code>phaseId</code>
+     * equals {@link PhaseId#RENDER_RESPONSE}, then obtain the state by calling
+     * {@link StateManager#getViewState} and write out it as an update element
+     * with an identifier of
+     * <code>&lt;VIEW_ROOT_CONTAINER_CLIENT_ID&gt;&lt;SEP&gt;javax.faces.ViewState</code>
+     * where <code>&lt;VIEW_ROOT_CONTAINER_CLIENT_ID&gt;</code> is the return
+     * from {@link UIViewRoot#getContainerClientId(FacesContext)} on the view
+     * from whence this state originated, and <code>&lt;SEP&gt;</code> is the
+     * currently configured
+     * {@link UINamingContainer#getSeparatorChar(FacesContext)}.</p>
+     *
      * @param phaseId the {@link javax.faces.event.PhaseId} that indicates
      * the lifecycle phase the components will be processed in. 
      */ 

PartialResponseWriter#startDocument()

@@ -113,6 +116,10 @@ public class PartialResponseWriter extends ResponseWriterWrapper {
 
     /**
      * <p class="changed_added_2_0">Write the start of a partial response.</p>
+     * <p class="changed_added_2_3">If {@link UIViewRoot} is an instance of
+     * {@link NamingContainer}, then write
+     * {@link UIViewRoot#getContainerClientId(FacesContext)} as value of the
+     * <code>id</code> attribute of the root element.</p>
      *
      * @throws IOException if an input/output error occurs
      * @since 2.0

jsf.ajax.request

@@ -2048,7 +2061,8 @@ if (!((jsf && jsf.specversion && jsf.specversion >= 20000 ) &&
              * <p><b>Implementation Requirements:</b></p>
              * This function must:
              * <ul>
-             * <li>Be used within the context of a <code>form</code>.</li>
+             * <li>Be used within the context of a <code>form</code><span class="changed_added_2_3">,
+             * else throw an error</span>.</li>
              * <li>Capture the element that triggered this Ajax request
              * (from the <code>source</code> argument, also known as the
              * <code>source</code> element.</li>
@@ -2059,6 +2073,16 @@ if (!((jsf && jsf.specversion && jsf.specversion >= 20000 ) &&
              * <li>If the <code>source</code> argument is a <code>string</code>, find the
              * DOM element for that <code>string</code> identifier.
              * <li>If the DOM element could not be determined, throw an error.</li>
+             * <li class="changed_added_2_3">If the <code>javax.faces.ViewState</code> 
+             * element could not be found, throw an error.</li>
+             * <li class="changed_added_2_3">If the <code>javax.faces.ViewState</code> 
+             * element has a <code>&lt;update id="&lt;VIEW_ROOT_CONTAINER_CLIENT_ID&gt;&lt;SEP&gt;</code>
+             * prefix, where &lt;SEP&gt; is the currently configured
+             * <code>UINamingContainer.getSeparatorChar()</code> and
+             * &lt;VIEW_ROOT_CONTAINER_CLIENT_ID&gt; is the return from
+             * <code>UIViewRoot.getContainerClientId()</code> on the
+             * view from whence this state originated, then remember it as <i>namespace prefix</i>.
+             * This is needed during encoding of the set of post data arguments.</li>
              * <li>If the <code>onerror</code> and <code>onevent</code> arguments are set,
              * they must be functions, or throw an error.
              * <li>Determine the <code>source</code> element's <code>form</code>
@@ -2175,7 +2199,10 @@ if (!((jsf && jsf.specversion && jsf.specversion >= 20000 ) &&
              * </li>
              * </ul>
              * </li>
-             * <li>Encode the set of post data arguments.</li>
+             * <li>Encode the set of post data arguments. <span class="changed_added_2_3">
+             * If the <code>javax.faces.ViewState</code> element has a namespace prefix, then
+             * make sure that all post data arguments are prefixed with this namespace prefix.
+             * </span></li>
              * <li>Join the encoded view state with the encoded set of post data arguments
              * to form the <code>query string</code> that will be sent to the server.</li>
              * <li>Create a request <code>context</code> object and set the properties:

jsf.ajax.response

@@ -2613,8 +2639,9 @@ if (!((jsf && jsf.specversion && jsf.specversion >= 20000 ) &&
              * correctness in parity with what is done in the
              * corresponding non-partial JSF view.  Locate and update
              * the <code>javax.faces.ViewState</code> value for all
-             * forms specified in the <code>render</code> target
-             * list.</li>
+             * POST forms covered in the <code>render</code> target
+             * list whose ID starts with the same 
+             * &lt;VIEW_ROOT_CONTAINER_CLIENT_ID&gt; value.</li>
 
              * <li class="changed_added_2_2">If an
              * <code>update</code> element is found in the response with
@@ -2639,8 +2666,9 @@ if (!((jsf && jsf.specversion && jsf.specversion >= 20000 ) &&
              * correctness in parity with what is done in the
              * corresponding non-partial JSF view.  Locate and update
              * the <code>javax.faces.ClientWindow</code> value for all
-             * forms specified in the <code>render</code> target
-             * list.</li>
+             * POST forms covered in the <code>render</code> target
+             * list whose ID starts with the same 
+             * &lt;VIEW_ROOT_CONTAINER_CLIENT_ID&gt; value.</li>
 
 
              * <li>If an <code>update</code> element is found in the response with the identifier
Comment by Neil Griffin [ 25/Jun/16 ]

@balusc: Thank you for making the commit. I hope to have time on Monday June 25 to review the code changes.

Comment by Neil Griffin [ 27/Jun/16 ]

@balusc: On line 1022 of Util.java, instead of:

Util.java
return viewRoot.getContainerClientId(context) + UINamingContainer.getSeparatorChar(context);

Would you instead consider:

Util.java
return viewRoot.getContainerClientId(context);

I admit that it is inconsistent to have UIInput name attribute values to be rendered as namespace + ":" + clientId but not include ":" for hidden fields like javax.faces.ViewRoot.

However, that's the way it was implemented in Mojarra 2.2 and it fits more naturally with the Faces Bridge as well as the method of namespacing parameters encouraged by the Portlet API. Thank you.

Comment by balusc [ 28/Jun/16 ]

How does that work for regular input fields? They are also namespaced this way. With those JSF API changes, it should theoretically not be necessary anymore to override the request parameter map this way and just rely on standard JSF implementation. Those API changes are meant to further reduce code in Portlet bridge and let JSF do the work.

Comment by Neil Griffin [ 28/Jun/16 ]

The Faces Bridge's implementation of ExternalContext.getRequestParameterMap() decorates a PortletRequest, so it is not possible to use com.sun.faces.context.RequestParameterMap since it decorates a ServletRequest.

The reason why input fields work is because decode methods automatically include the namespace prefix (and the separator char) by asking for a parameter value with getClientId() as the parameter name, like this:

FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(uiInput.getClientId());

For example, see HtmlBasicRenderer.java

Lookups for request parameters like javax.faces.ViewState do not automatically include the namespace prefix, which means that the Faces Bridge's implementation of ExternalContext.getRequestParameterMap() must account for this.

A good example is ResponseStateManagerImpl.java.

Comment by balusc [ 04/Jul/16 ]

I see, the problem boils down to that JSF impl is internally not prefixing the standard parameters with naming container client ID when the UIViewRoot is an instance of NamingContainer. If that part is fixed, then the whole RequestParameterMap approach becomes unnecessary. And, then the portlet case will also start to work correctly, right?

Comment by balusc [ 04/Jul/16 ]

Neil/Werpu, how about this change on UIViewRoot#encodeChildren()?

     * <p class="changed_added_2_3">If this {@link UIViewRoot} is an instance of {@link NamingContainer}, then the JSF
     * implementation must ensure that all encoded POST request parameter names are prefixed with
     * {@link UIViewRoot#getContainerClientId(FacesContext)} as per rules of {@link UIComponent#getClientId(FacesContext)}.
     * This also covers all predefined POST request parameters such as {@link ResponseStateManager#VIEW_STATE_PARAM},
     * {@link ClientBehaviorContext#BEHAVIOR_SOURCE_PARAM_NAME} and {@link PartialViewContext#PARTIAL_EVENT_PARAM_NAME}.
     * </p>
 

I implemented this locally on Mojarra and all unit tests have passed. I didn't yet remove Mojarra internal RequestParameterMap just to ensure backwards compatibility.

Comment by balusc [ 06/Jul/16 ]

Neil, above proposed implementation changes have been committed as per https://java.net/projects/mojarra/sources/git/revision/3b1d1e2a1330c6789f566f36597b6b9fcb81d509 so you have the opportunity to test it against your Portlet case.

Only API change (the above Javadoc proposal) has not been committed yet due to lack of confirming feedback.

Comment by lu4242 [ 20/Jul/16 ]

Other post parameters that could be included are javax.faces.RenderKitId (ResponseStateManager#RENDER_KIT_ID_PARAM) and javax.faces.ClientWindow (ResponseStateManager#javax.faces.ClientWindow).

Comment by balusc [ 20/Jul/16 ]

Indeed. There are more. Should we specify them all? I have in Mojarra at least collected them as RenderKitUtils.PredefinedPostbackParameter enum. There are so far 9 of those: https://github.com/javaserverfaces/mojarra/blob/3b1d1e2a1330c6789f566f36597b6b9fcb81d509/jsf-ri/src/main/java/com/sun/faces/renderkit/RenderKitUtils.java#L181

Comment by balusc [ 21/Jul/16 ]

I've pushed the javadoc changes: https://java.net/projects/mojarra/sources/git/revision/1569145562d8c20cc924f0eb5343b5e931df352d. For now, the issue is technically solved in JSF API and Mojarra impl.

Before I close off the issue, please let me know if there are any things unclear or missing, particularly with regard to Portlets and MyFaces.

Comment by werpu [ 21/Jul/16 ]

Hi sorry for being so silent, fact is I was extremely busy. I will check the changes tonight and will give my comment either tonight or tomorrow morning. So please keep the issue open at least until tomorrow.

Comment by werpu [ 21/Jul/16 ]

Ok, again sorry for not commenting on this issue for such a long time, I personally like the ViewRoot prepending to javax.faces.ViewState in the id is a reasonable way to go. I can only comment on the ajax client side however. I personally think this solves the problem for me. The original problem was as far as I remember that in the original specs following was written.

If an update element is found in the response with the identifier javax.faces.ViewState:
<update id="javax.faces.ViewState">
<![CDATA[...]]>
</update>
locate and update the submitting form's javax.faces.ViewState value with the CDATA contents from the response.

Which was clearly wrong, since the viewstate should be the same for all forms under one viewroot. Adding the viewroot id fixes this problem once and for all for all cases.
Thanks for your efforts on fixing this long outstanding issue.

Comment by balusc [ 21/Jul/16 ]

Great, thank you for your feedback! Now yet a confirmation from Portlet guys.

Comment by Neil Griffin [ 22/Jul/16 ]

@balusc: I have begun reviewing your recent commits for this issue. Also, I have rebuilt Mojarra 2.3.0-m07 from source and have it running under Pluto 3.0. My goal is to report back tomorrow with more information. Thanks for your patience, Neil.

Comment by Neil Griffin [ 23/Jul/16 ]

@balusc: I have done preliminary testing and have seen good results so far. I still need to do more testing so I ask that you please keep this issue open. Regarding the namespace prefix, please consider the changes in the following pull request: https://github.com/javaserverfaces/mojarra/pull/3

The changes in the pull request remove the separator char from the namespace prefix. That's the way it is implemented in Mojarra 2.2 and it fits more naturally with the Faces Bridge as well as the method of namespacing parameters encouraged by the Portlet API. In addition, component suites like PrimeFaces and ICEfaces namespace their own predefined postback parameters without using the separator char. Thank you.

Comment by balusc [ 23/Jul/16 ]

Namespacing without separator character does not fit naturally in JSF API. I imagined that doing all the namespacing job in JSF side should reduce the work in the Faces Bridge. What work exactly is left in the Faces Bridge that it still needs its own way of namespacing? Then we can look for ways reducing/removing that work. Perhaps a new JSF API method to obtain a namespaced predefined postback parameter without the need to manually check and prefix it?





[JAVASERVERFACES_SPEC_PUBLIC-1418] CDI replacement for @ManagedProperty Created: 26/May/16  Updated: 01/Jun/16

Status: In Progress
Project: javaserverfaces-spec-public
Component/s: EL
Affects Version/s: None
Fix Version/s: 2.3

Type: New Feature Priority: Major
Reporter: arjan tijms Assignee: arjan tijms
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to JAVASERVERFACES-4149 Implement CDI replacement for @Manage... In Progress

 Description   

In JAVASERVERFACES_SPEC_PUBLIC-1417 the javax.faces.bean was deprecated. Pretty much everything in that package has a replacement elsewhere, except for @ManagedProperty.

Therefor I'd like to propose providing a CDI based replacement for @ManagedProperty. This should effectively evaluate an EL expression (using the JSF native EL facility) and inject the result into the target injection point.






[JAVASERVERFACES_SPEC_PUBLIC-1372] f:ajax doesn't validate client ID anymore - confusing to starters Created: 20/Mar/15  Updated: 19/Jul/16

Status: In Progress
Project: javaserverfaces-spec-public
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: balusc Assignee: balusc
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Trigger: https://java.net/jira/browse/JAVASERVERFACES-2958

Being able to reference a specific ui:repeat/h:dataTable item via f:ajax render is absolutely a major step forward.

However, the change is a bit overzealous. The f:ajax does not throw an exception anymore on a really invalid ID. This is confusing to starters. This check should be brought back. Instead, the algorithm should be changed to strip any iteration index from the given client ID using the following helper method before scanning the component tree:

private static String stripIterationIndexFromClientId(String clientId) {
	String separatorChar = Character.toString(UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance()));
	String quotedSeparatorChar = Pattern.quote(separatorChar);
	return clientId.replaceAll(quotedSeparatorChar + "[0-9]+" + quotedSeparatorChar, separatorChar);
}

If the component is still not found, then throw the FacesException as it did before.

It would be great to also specify it somewhere in the spec as e.g. MyFaces <f:ajax> and PrimeFaces <p:ajax> doesn't implement it.



 Comments   
Comment by Manfred Riem [ 24/Mar/15 ]

Validating the client ids for f:ajax does not seem to be specified by any spec requirements. While I agree it would be good to determine what needs to be done this should be addressed by a specification issue, before we continue. Can you please file the associated issue and discuss it in the EG?

Comment by balusc [ 26/Aug/15 ]

We could alternatively improve findComponent() spec and algorithm to cover the iteration index.





[JAVASERVERFACES_SPEC_PUBLIC-1423] Dynamic resource loading in ajax requests Created: 16/Jun/16  Updated: 22/Jul/16

Status: In Progress
Project: javaserverfaces-spec-public
Component/s: Components/Renderers, Resources
Affects Version/s: 2.2
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: tandraschko Assignee: balusc
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently if you dynamically add components via java code on a ajax postback, and the component type was not available in the initial request, the component probably missing it's required scripts/styles.
The same applies for dynamic ui:includes with a EL as src attribute.

The problem actually occurs with any JSF library.

The initial solution in PF was custom JS which checks if the script is included, otherwise we loaded the required styles/scripts.

The new solution is the following:

  • remember all resources with a RESTORE_VIEW phaselistener
  • in our PrimePartialResponseWriter (before RENDER_RESPONSE), we loop the current resources and create a diff
  • for the diff (new resources), we ask the resourceHandler#createResource for the URL and pass them to the client via ajax eval tag

AFAIK MyFaces Core already implemented something similiar.

Probably it's enough the describe the feature in the specs, there is no need to adding new API classes.
A param to deactive the feature woudl be great.



 Comments   
Comment by balusc [ 20/Jun/16 ]

Related:

Comment by stiemannkj1 [ 01/Jul/16 ]

In order to understand this issue better, I created a reproducer here: https://github.com/stiemannkj1/dynamic-resource-loading-ajax-reproducer

As tandraschko said, the problem occurs when you try to do something like the following:

Application application = FacesContext.getCurrentInstance().getApplication();
// exampleComponent has an @ResourceDependency on example.js
UIComponent exampleComponent = application.createComponent(ExampleComponent.COMPONENT_TYPE);
UIComponent parent = actionEvent.getComponent().getParent();
parent.getChildren().add(exampleComponent);

When that code is run, the @ResourceDependency s of exampleComponent are not loaded.

The problem also occurs when the src attribute of a ui:include is changed during Ajax, and the included ui:composition contains a component with an @ResourceDependency (the resource dependency is never loaded):

<h:form>
    <ui:include id="include" src="#{bean.include}" /><br />
    <h:commandButton value="Toggle Include" actionListener="#{bean.toggleInclude}">
        <f:ajax render="@form" />
    </h:commandButton>
</h:form>
public void toggleInclude() {

    if ("includeText.xhtml".equals(getInclude())) {
        // Contains example:component which has an @ResourceDependency on example.js
        setInclude("includeExample.xhtml");
    }
    else {
        setInclude("includeText.xhtml");
    }
}

I'll try to add some comments about how to implement this feature in a way that will work for JSF portlets soon.

- Kyle

Comment by stiemannkj1 [ 05/Jul/16 ]

The solution proposed by BalusC's would work for portlets, but it would need to be modified. The server-side solution of keeping a list of rendered resources somehow (likely using the JAVASERVERFACES_SPEC_PUBLIC-1404 solution) and doing a diff of what's rendered or not rendered would work fine with portlets. However the client-side aspect of "...passing resource path to JS and have it check if it's already in DOM and if not, then dynamically create script element." would need to be modified slightly. The problem with relying on the resource path is that portlet containers have full control of URLs and there is no guarantee that a resource URL will appear in the DOM in a parseable form. On top of that, resource URLs in Liferay and Pluto (the Portlet Container reference implementation) provide the resource library and name as parameters: portal/url?ln=library-name&javax.faces.resource=resource-name.js. Finally, in a portlet environment those parameter names are supposed to be prefixed with the portlet's namespace. Therefore, relying on the resource path on the client-side would be too hard (too many possible corner cases). Instead I propose that resources loaded during Ajax be loaded via and API like this:

resourceLoader.load('resource-library:resource-name', 'some/url/to/resource-name.js');

// resourceLoader.load() does something like this:
// if (!loadedResourceSet.contains('resource-library:resource-name')) {
//     // dynamically load the resource
// }

This would also require that resources loaded during a non-Ajax request be added to the loadedResourceSet:

<script type="text/javascript" src="some/url/to/resource-name.js" />
<script>
    resourceLoader.addLoadedResource('resourceLibrary:resourceName');
</script>

Finally, since the portlet container might need to be made aware that a resource has been loaded via Ajax, jsf.js would need to fire an event like resourceLoaded which would contain the resource URL and resource id.

Comment by balusc [ 22/Jul/16 ]

JAVASERVERFACES_SPEC_PUBLIC-1404 has been implemented. There's now a ResourceHandler#markResourceRendered() and isResourceRendered(). It should be trivial to re-mark the resources as rendered during restore view phase, provided that any dynamic resources are properly been added as component resources. I'm currently looking for the best place for that in API/impl.

Comment by balusc [ 22/Jul/16 ]

I created a bunch of test cases in order to reproduce and inspect the problem in below cases performed in the same view, invoked in arbitrary amount and order:

  • component resource added via view.addComponentResource(context, script, "head").
  • component resource added via view.addComponentResource(context, script, "body").
  • component resource added via parent.getChildren().add(componentWithResourceDependency).
  • component resource added via dynamic include referring component with resource dependency.

In all cases (at least in Mojarra) the view is properly restored with information about which resources have already been added during previous postbacks (via restore dynamic actions). In other words, view.getComponentResources() returns the correct information already. Indeed a diff on this during pre render view would have been sufficient in order to detect new resources. It looks like UIViewRoot#addComponentResource() is the best place to collect this information and PartialViewContext#processPartial() is the best place to render missing script resources (only if getRenderAll() is false). I was thinking about reusing update id="javax.faces.ViewHead" which is currently unimplemented in Mojarra's jsf.js. It merely throws a JS error saying that browsers doesn't support replacing head itself: https://github.com/javaserverfaces/mojarra/blob/a3f6431b9bde82b689540fc44ae0925baea2a9b7/jsf-api/src/main/resources/jsf.js#L1401 This is true, but browsers actually support manipulating head's contents (i.e. create script element and add it to head), so we could go on this route.

Issues yet to investigate:

  • how to deal with stylesheet resources
  • how exactly to implement processPartial() + javax.faces.ViewHead update
  • how would that work in Portlets as it doesn't seem to have a notion of "HTML head"
Comment by balusc [ 22/Jul/16 ]

Those are the test cases: https://java.net/projects/mojarra/sources/git/revision/dcf22c7d30ec251fc34942b7bb5cfdb72a80931f





Generated at Sat Jul 23 13:34:55 UTC 2016 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.