Search code examples
jsfjsf-2.2faces-flow

Target Unreachable, identifier 'flowScope' resolved to null


I'm exploring the Faces Flow feature in JSF 2.2 and I'm getting the following error Target Unreachable, identifier 'flowScope' resolved to null when I run the tutorial in this page: http://www.mastertheboss.com/javaee/jsf/faces-flow-tutorial

The sample seems to be really simple, it only have one flow with 3 facelets, with this structure:

enter image description here

The flow is called signup, so I have a folder called signup in inside my WebContent folder, and 3 facelets, one of them with the same name as the flow as starting node, and a configuration file called signup-flow.xml.

This is the content of the starting node (signiup.xhtml):

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Signup account</title>
<meta http-equiv="Content-Type"
    content="application/xhtml+xml; charset=UTF-8" />
</h:head>
<h:body>
    <h:form id="form1" styleClass="form">
        <h1>Signup Account</h1>
        <p>Name <h:inputText id="name" value="#{flowScope.name}" /></p>
        <p>Surname: <h:inputText id="surname" value="#{flowScope.surname}" /></p>
        <p>Email: <h:inputText id="email" value="#{flowScope.email}" /></p>     

        <p><h:commandButton id="page2" value="next" action="signup2" /></p>

    </h:form>
</h:body>
</html>

This is my SignupBean:

package com.jsf.flow;

import java.io.Serializable;

import javax.inject.Named;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.flow.FlowScoped;

@Named
@FlowScoped(value="signup")
public class SignupBean implements Serializable {

    private static final long serialVersionUID = 8112971305468080981L;
    private boolean licenseAccepted;

    public SignupBean() { 
    }

    public String getHomeAction() {
        return "/index";
    }
    public boolean isLicenseAccepted() {
        return licenseAccepted;
    }

    public void setLicenseAccepted(boolean licenseAccepted) {
        this.licenseAccepted = licenseAccepted;
    }

    public String accept() {
        if (this.licenseAccepted) {
            return "signup3";
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "You have to read and accept the license!", "You have to read and accept the license!"));
            return null;
        }
    }
}

And this is my signup-flow.xml:

<?xml version='1.0' encoding='UTF-8'?>

<faces-config
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
    version="2.2">

    <flow-definition id="signup">
        <flow-return id="homePage">
            <from-outcome>#{signupBean.homeAction}</from-outcome>
        </flow-return>
    </flow-definition>
</faces-config>

I get the error when I click on the commandButton in the signup.xhtml, the code seems to be exactly the same as the one in the tutorial, I checked several posts with the same error but nothing seems to work for me.

This is the important part in the stack trace:

javax.el.PropertyNotFoundException: /signup/signup.xhtml @12,68 value="#{flowScope.name}": Target Unreachable, identifier 'flowScope' resolved to null
    at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:95)

Worth to mention that I'm using GlassFish 4.


Solution

  • Found the problem, I was trying to start the flow calling the initial node using a link, like this:

    <h:link id="link1" styleClass="link" value="Link" outcome="/signup/signup.xhtml"></h:link>
    

    Instead I replaced the link with a commandButton and in the action parameter I used the flow name, like this:

    <h:commandButton id="start" value="Signup User" action="signup"/>
    

    And now it's working.