New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View not destroyed when closing browser tab on page backed by omnifaces @ViewScoped #208

Closed
wfsaxton opened this Issue Feb 11, 2016 · 6 comments

Comments

Projects
None yet
2 participants
@wfsaxton

wfsaxton commented Feb 11, 2016

I set the view/logical view limits to 3 and deployed a simple JSF page with omnifaces ViewScoped backing bean. Closing tabs does not appear to do anything. I would have expected the secondary beans to have been destroyed so that the first bean is never automatically expired.

I'm using GF 4.1, JSF 2.2, Omnifaces 2.2

Steps to reproduce:

  1. Open viewBean.xhtml in one tab
  2. Open viewBean.xhtml in another tab, close the tab
  3. Open viewBean.xhtml in another tab, close the tab
  4. Open viewBean.xhtml in another tab, close the tab
  5. Open viewBean.xhtml in another tab, close the tab
  6. On the original tab, click the button. Get the following error:

javax.faces.application.ViewExpiredException: viewId:/viewBean.jsf - View /viewBean.jsf could not be restored.

web.xml:

    <context-param>
        <param-name>com.sun.faces.numberOfViewsInSession</param-name>
        <param-value>3</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.numberOfLogicalViews</param-name>
        <param-value>3</param-value>
    </context-param>

ViewBean.java:

package com.example.zunload;

import java.io.Serializable;
import javax.inject.Named;
import org.omnifaces.cdi.ViewScoped;

@Named
@ViewScoped
public class ViewBean implements Serializable {

    String testString = "Hello World";

    public ViewBean() {
    }

    public String getTestString() {
        return testString;
    }

    public void listener() {
        System.out.println("Do this");
    }
}

viewBean.xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>TODO supply a title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </h:head>
    <h:body>
        <div>#{viewBean.testString}</div>

        <h:form>
            <h:commandButton value="Submit" actionListener="#{viewBean.listener}"/>
        </h:form>
    </h:body>
</html>

@wfsaxton wfsaxton changed the title from View not destroyed when closing browser tab on page using @ViewScoped to View not destroyed when closing browser tab on page backed by omnifaces @ViewScoped Feb 11, 2016

BalusC added a commit that referenced this issue Feb 11, 2016

#208: Fire PreDestroyViewMapEvent instead of manually calling it.
Unfortunately neither Mojarra nor MyFaces would clean up server side
view state on this, but this is at least a start.
@BalusC

This comment has been minimized.

Show comment
Hide comment
@BalusC

BalusC Feb 11, 2016

Member

Reproduced. Nice find. Unfortunately, neither Mojarra nor MyFaces keeps server side view state "in sync" with PreDestroyViewMapEvent, so those server side view states still stick around. Your best bet is using client side state saving instead.

Theoretically, we could solve this by providing our own server side state manager, but this is not a trivial task. I'd rather first look how the JSF API itself can be improved with regard to this.

Member

BalusC commented Feb 11, 2016

Reproduced. Nice find. Unfortunately, neither Mojarra nor MyFaces keeps server side view state "in sync" with PreDestroyViewMapEvent, so those server side view states still stick around. Your best bet is using client side state saving instead.

Theoretically, we could solve this by providing our own server side state manager, but this is not a trivial task. I'd rather first look how the JSF API itself can be improved with regard to this.

@BalusC

This comment has been minimized.

Show comment
Hide comment
@BalusC

BalusC Feb 11, 2016

Member

For now, I added a hack to explicitly remove Mojarra's server side view state. Your use case now works fine for me. It's available in today's 2.3 snapshot.

Will look at MyFaces later.

Member

BalusC commented Feb 11, 2016

For now, I added a hack to explicitly remove Mojarra's server side view state. Your use case now works fine for me. It's available in today's 2.3 snapshot.

Will look at MyFaces later.

@wfsaxton

This comment has been minimized.

Show comment
Hide comment
@wfsaxton

wfsaxton Feb 12, 2016

Thank you, @BalusC I assume no release date for 2.3 as it will be released "when its good and ready" !

wfsaxton commented Feb 12, 2016

Thank you, @BalusC I assume no release date for 2.3 as it will be released "when its good and ready" !

@BalusC

This comment has been minimized.

Show comment
Hide comment
@BalusC

BalusC Feb 12, 2016

Member

When I'm 100% satisfied with o:socket. It's getting close :)

Member

BalusC commented Feb 12, 2016

When I'm 100% satisfied with o:socket. It's getting close :)

@BalusC

This comment has been minimized.

Show comment
Hide comment
@BalusC

BalusC Feb 12, 2016

Member

MyFaces way of keeping track of views is kind of convoluted (see last commit), but your use case now also works fine for me in MyFaces.

Member

BalusC commented Feb 12, 2016

MyFaces way of keeping track of views is kind of convoluted (see last commit), but your use case now also works fine for me in MyFaces.

@BalusC

This comment has been minimized.

Show comment
Hide comment
@BalusC

BalusC Feb 12, 2016

Member

It's available in today's 2.3 snapshot.

Member

BalusC commented Feb 12, 2016

It's available in today's 2.3 snapshot.

@BalusC BalusC closed this Feb 12, 2016

BalusC added a commit that referenced this issue Feb 13, 2016

BalusC added a commit that referenced this issue Feb 15, 2016

#208: Further improved view scope destroy, it will now also destroy any
JSF own view scoped beans (javax.faces.bean/view.ViewScoped) associated
with the view (only if the view has an OmniFaces CDI view scoped of
course). Also, any component event listeners on UIViewRoot will be
restored and those listening on PreDestroyViewMapEvent will be invoked.

BalusC added a commit that referenced this issue Mar 8, 2016

#208: tested showcase on MyFaces, fixed a corner case with unload script
(MyFaces autogenerated an ID which wasn't re-generated in postback,
causing corrupted view state during unload)

BalusC added a commit that referenced this issue Mar 15, 2016

#208: Fixed corner case bug when stateless JSF is used with @ViewScoped
(though using @ViewScoped beans in stateless JSF doesn't make sense)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment