2

I am reading a Java EE 7 book "Java EE 7 Recipes" by Josh Juneau. I am trying to run some sample code from chapter 3 (Recipe 3.5 ) to test the conditional navigation. The code is very simple and straightforward but unfortunately I am getting very odd behavior.

JSF Page script is given below:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
    <title>Login Test</title>
</h:head>
    <h:body>
        <h:form id="resourceTest">            
            <h1>Login</h1>
            <h:commandButton id="loginButton" action="#{loginTest.login}" value="Login" />
        </h:form>
    </h:body>
</html>

and the JSF Managed Bean:

package com.test.controller;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class LoginTest {

private boolean authenticated;

public LoginTest() {
    authenticated = false;
}

public boolean isAuthenticated() {
    return authenticated;
}

public void setAuthenticated(boolean authenticated) {
    this.authenticated = authenticated;
}

public void login(){
    setAuthenticated(true);
}


}

faces-config.xml

<navigation-rule>
    <navigation-case>
        <from-action>#{loginTest.login}</from-action>
        <if>#{loginTest.authenticated}</if>
        <to-view-id>/faces/nextpage.xhtml</to-view-id>
        <redirect/>
    </navigation-case>
</navigation-rule>

When I click on the Login button it generates an exception Argument Error: Parameter id is null

Stacktrace is given below:

[2013-11-22T10:28:14.893+0000] [glassfish 4.0] [WARNING] [] [javax.enterprise.resource.webcontainer.jsf.lifecycle] [tid: _ThreadID=20 _ThreadName=http-listener-1(3)] [timeMillis: 1385116094893] [levelValue: 900] [[
Argument Error: Parameter id is null
java.lang.NullPointerException: Argument Error: Parameter id is null
at com.sun.faces.util.Util.notNull(Util.java:425)
at com.sun.faces.flow.FlowHandlerImpl.getFlow(FlowHandlerImpl.java:89)
.....
.....
at java.lang.Thread.run(Thread.java:724)
]]
[2013-11-22T10:28:14.909+0000] [glassfish 4.0] [FATAL] [jsf.context.exception.handler.log] [javax.enterprise.resource.webcontainer.jsf.context] [tid: _ThreadID=20 _ThreadName=http-listener-1(3)] [timeMillis: 1385116094909] [levelValue: 1100] [[
JSF1073: javax.faces.FacesException caught during processing of INVOKE_APPLICATION 5 : UIComponent-ClientId=, Message=Argument Error: Parameter id is null]]
[2013-11-22T10:28:14.909+0000] [glassfish 4.0] [FATAL] [] [javax.enterprise.resource.webcontainer.jsf.context] [tid: _ThreadID=20 _ThreadName=http-listener-1(3)] [timeMillis: 1385116094909] [levelValue: 1100] [[
Argument Error: Parameter id is null
javax.faces.FacesException: Argument Error: Parameter id is null
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:89)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
..........
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.NullPointerException: Argument Error: Parameter id is null
at com.sun.faces.util.Util.notNull(Util.java:425)
at com.sun.faces.flow.FlowHandlerImpl.getFlow(FlowHandlerImpl.java:89)
at com.sun.faces.application.NavigationHandlerImpl.determineViewFromActionOutcome(NavigationHandlerImpl.java:1204)
....
]]

Am I missing something?

Furthermore, if I change the EL expression in my JSF page to #{loginTest.login()} (i.e. append parenthesis), I don't get any error message but the redirection doesn't work. Does this make any difference?

1 Answer 1

7

I reproduced it. It's a bug in Mojarra which has the same grounds as issue 3054 which I already reported earlier. If there's no flow document ID in the navigation case, the NavigationCase#getToFlowDocumentId() returns an empty string, never null, yet the code is performing only a null check.

I've reported this bug as issue 3087. The fix shall hopefully be in 2.2.5. In the meanwhile, your best bet is forgetting navigation cases and using implicit navigation. Edit the login method as follows:

public String login() {
    setAuthenticated(true);
    return "/faces/page.xhtml?faces-redirect=true";
}

And get rid of that navigation case.

Sign up to request clarification or add additional context in comments.

2 Comments

That make sense. However what about using parenthesis in the EL expressions after the function name. If I use parenthesis in the EL expression like "#{loginTest.login()}" It doesn't do anything.
Because it didn't match the <from-action> which is compared as a literal string. As you returned void from action method, and no navigation case matched, by default the same view is returned. If you edit the <from-action> to include the parentheses, then you'll see that it "works" (it'll still fail with the NPE, but it's at least matched :) ).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.