Search code examples
jsfjsf-2view-scopesession-scopetcserver

Local tc Server 3.1 instance ends @ViewScoped and @SessionScoped beans


UPDATE:

Any @ViewScoped and @SessionScoped beans' lifecycles are not what would be expected. That is, they are ending sooner than they should. For instance, when an ajax postback is done where the method returns void neither @ViewScoped or @SessionScoped beans should end, but they do.

After deploying it to our development environment and others testing it, it seems like it only occurs on my machine and when locally ran. No idea why. tc Server 3.1 is what is being used.

I'm leaving the original in case someone comes upon the issue similarly.

Original:

I have a tree that is populated by a ViewScoped that reads data from an XML file and creates TreeNode objects for it. Performance isn't super quick so it being created in the view once is ideal. (Some of the code has been omitted below, the functionality does work though)

@ManagedBean
@ViewScoped
public class FundsXmlTreeBuilder implements Serializable {

    private TreeNode root;

    public FundsXmlTreeBuilder() throws SAXException, IOException, ParserConfigurationException {
        root = new DefaultTreeNode("Root", null);
        buildTree();
    }

    public void buildTree() throws SAXException, IOException, ParserConfigurationException {
        //reads xml file and adds TreeNodes
    }
}

There is another RequestScoped bean that has a method that handles the ajax event of a tree node being selected in the onNodeSelect method. It basically determines how another part of the page will be shown.

@ManagedBean
@RequestScoped
public class FundsXmlDisplay implements Serializable{

    private Fund fund;
    private FundFamily fundFamily;
    private FocusedPortfolioModel model;

    public TreeNode selectedRoot;

    public FundsXmlDisplay() {
        fund = null;
        fundFamily = null;
        model = null;

        selectedRoot = null;
    }

    public void onNodeSelect(NodeSelectEvent event) {
        Object data = event.getTreeNode().getData();

        fund = null;
        fundFamily = null;
        model = null;
        if (data instanceof Fund) {
            fund = (Fund) data;
        } else if (data instanceof FundFamily) {
            fundFamily = (FundFamily) data;
        } else if (data instanceof FocusedPortfolioModel) {
            model = (FocusedPortfolioModel) data;
            model.createPieModel();
        }
    }
}

Here are the main portions of the markup.

<h:body>

    <h:form styleClass="form" id="form1">
        *** For Home Office Use Only
        <br />

        <p:layout id="xmlArea"
            style="min-width:400px;min-height:600px;width:95%;">
            <p:layoutUnit id="xmlTree" position="west" resizable="false"
                closable="false" scrollable="true" size="25%" minSize="40"
                maxSize="400" style="padding:.25em;" header="Funds XML Elements">
                    <p:tree value="#{fundsXmlTreeBuilder.root}" var="node"
                        dynamic="false" selectionMode="single">
                        <p:ajax event="select" update=":form1:xmlDisplay"
                            listener="#{fundsXmlDisplay.onNodeSelect}" />
                        <p:treeNode>
                            <h:outputText value="#{node}" style="font-size:small" />
                        </p:treeNode>
                    </p:tree>
            </p:layoutUnit>

            <p:layoutUnit position="center" header="Element Detail" size="75%">
                <p:scrollPanel id="xmlDisplay" mode="native"
                    style="height:100%;">
                    ...
                </p:scrollPanel>
            </p:layoutUnit>
        </p:layout>
    </h:form>

</h:body>

The issue I am having is that FundsXmlTreeBuilder is recreated after the ajax event is fired, but before the listener. I would expect it to not be recreated at all since, from what I understand, the view is not changing.

There are quite a few rendered attributes in the xmlDisplay area. Not sure if that is relevant. I understand that a view lives when an action method returns null or void, but I don't think the rendered methods being used count as "action methods".

What is also interesting, if I change FundsXmlTreebuilder to be SessionScoped it gets recreated after selecting a node too, which is really what has stumped me.

Hope everything is clear and enough information is given. Thanks!


Solution

  • In the web.xml, the <secure> tag needed to be commented out. So it the corresponding section looks like:

    <session-config>
        <session-timeout>60</session-timeout>
        <cookie-config>
            <http-only>true</http-only>
    <!--        <secure>true</secure> --> <-- Not be set locally -->
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>
    

    This tag tells the browser to only send the cookie on HTTPS transmission, which I do not believe to be the case when ran locally.

    This is where I found the explanation. A teammate discovered the fix.