My real use is a bit different, but I've narrowed the problem down to the code you see below. When you click the "go nowhere" button, all is well, no matter how many times you click it. But when you click "go somewhere", you get an IllegalStateException, "Component ID j_idt3:fnord1 has already been found in the view". Why does it work just fine returning null but not when you return a nav string?
I've read this answer, which is relevant, but doesn't have quite enough for my understanding. If there's a section in the jsf spec (or some such source) that is relevant, I'd greatly appreciate answers pointing it out.
/secure/application/sample.xhtml
:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:body>
<h:form>
<ul>
<li><h:commandLink action="#{sample.goNowhere}" value="go nowhere"/></li>
<li><h:commandLink action="#{sample.goSomewhere}" value="go somewhere"/></li>
</ul>
<h:selectOneMenu id="fnord0" binding="#{components.menuAddForm}">
<f:selectItem id="fnord1" itemLabel="---" noSelectionOption="true"/>
</h:selectOneMenu>
</h:form>
</h:body>
</html>
I don't need the ids, it just makes the error easier to read.
"components" is a request scoped hashmap, following the recommendation in this answer about component bindings.
Sample.java
:
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class Sample
{
private static final String somewhere = "/secure/application/sample.xhtml";
public String goNowhere()
{
System.out.println("goNowhere()");
return null;
}
public String goSomewhere()
{
System.out.println("goSomewhere()");
return somewhere;
}
}