PropertyNotFoundException - Target Unreachable
strickla May 23, 2007 5:48 PMHello all,
New to JSF and Seam here so I'm trying to work out a few kinks. I have created a simple JSF/Facelets application that "just worked" when deploying to JBoss AS 4.2.0 GA.
Converting that same application to take advantage of Seam has been a headache and a half. Currently everything seems to be good except that when my form on my Login.xhtml page attempts to submit I get the following error:
First, my environment: JBoss AS 4.2 GA, jboss-seam-CVS.20070521, java 1.5.0_06, MyEclipse 5.5 GA, Facelets 1.1.11.
javax.servlet.ServletException: /Login.xhtml @41,51 value="#{user.userName}": Target Unreachable, identifier 'user' resolved to null javax.faces.webapp.FacesServlet.service(FacesServlet.java:256) org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) root cause javax.el.PropertyNotFoundException: /Login.xhtml @41,51 value="#{user.userName}": Target Unreachable, identifier 'user' resolved to null com.sun.facelets.el.TagValueExpression.getType(TagValueExpression.java:62) com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:81) javax.faces.component.UIInput.getConvertedValue(UIInput.java:934) javax.faces.component.UIInput.validate(UIInput.java:860) javax.faces.component.UIInput.executeValidate(UIInput.java:1065) javax.faces.component.UIInput.processValidators(UIInput.java:666) javax.faces.component.UIForm.processValidators(UIForm.java:229) javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1030) javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:662) com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:100) com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251) com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117) javax.faces.webapp.FacesServlet.service(FacesServlet.java:244) org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
I have since modeled my application as closely as possible to the "registration" example that comes with the Seam CVS nightly build. The main differences being that I am deploying it as a WAR since I created the project w/out using the seam-gen utility. All libraries (jboss-seam.jar, jboss-seam-ui.jar, jsf-facelets.jar, jboss-el.jar) are in the WEB-INF/lib directory of the war.
Here is my backing bean code:
/** * */ package ***.***.netprov.bean; import static org.jboss.seam.ScopeType.SESSION; import java.io.Serializable; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; /** * @author strickla */ @Name("user") @Scope(SESSION) public class User implements Serializable { /** * The name of the user */ private String userName; /** * The password of the user */ private String userPassword; public User() { } public User(String userName, String userPassword) { this.userName = userName; this.userPassword = userPassword; } /** * @return the userName */ public String getUserName() { return userName; } /** * @param userName * the userName to set */ public void setUserName(String userName) { this.userName = userName; } /** * @return the userPassword */ public String getUserPassword() { return userPassword; } /** * @param userPassword * the userPassword to set */ public void setUserPassword(String userPassword) { this.userPassword = userPassword; } public String loginUser() { if ("myeclipse".equals(getUserName()) && "myeclipse".equals(getUserPassword())) { return "success"; } else { FacesContext fCtx = FacesContext.getCurrentInstance(); FacesMessage fMsg = new FacesMessage( "You have entered an invalid username and/or password."); fCtx.addMessage("loginForm", fMsg); return "failure"; } } }
and my stateless session bean:
package ***.***.netprov.bean; import java.util.Date; import javax.ejb.Stateless; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.log.Log; @Stateless @Name("login") public class LoginAction implements Login { @In(create=true) private User user; @Logger private static Log log; public String login() { log.info("User " + user.getUserName() + " attempted to log in @ " + new Date()); return user.loginUser(); } }
and finally, the Login.xhtml page:
<!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:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <head> <title>JSF Facelets 'Login' Page</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <meta http-equiv="pragma" content="no-cache" /> <meta http-equiv="cache-control" content="no-cache" /> <meta http-equiv="expires" content="0" /> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3" /> <meta http-equiv="description" content="This is my page" /> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <ui:composition template="./template.xhtml"> <ui:define name="title"> JSF Facelets Login Tutorial </ui:define> <ui:define name="body"> <f:loadBundle basename="mil.disa.netprov.MessageBundle" var="bundle"></f:loadBundle> <form jsfc="h:form" id="loginForm"> <table> <tr> <td> <label jsfc="h:outputLabel" value="#{bundle.userNameLabel}" for="userNameTxt" rendered="true"> <span jsfc="ui:remove">Username:</span> </label> </td> <td> <input jsfc="h:inputText" id="userNameTxt" required="true" rendered="true" value="#{user.userName}"></input> </td> </tr> <tr> <td> <label jsfc="h:outputLabel" value="#{bundle.userPasswordLabel}" for="userPasswordTxt" rendered="true"> <span jsfc="ui:remove">Password:</span> </label> </td> <td> <input jsfc="h:inputSecret" id="userPasswordTxt" redisplay="false" required="true" rendered="true" value="#{user.userPassword}"></input> </td> </tr> <tr> <td> <button jsfc="h:commandButton" id="submitButton" action="#{login.login}" rendered="true" value="#{bundle.loginButtonLabel}" /> </td> </tr> </table> </form> </ui:define> </ui:composition> </body> </html>
Can anyone tell me what I'm doing wrong? My gut instincts at this point are telling me that I should have started with seam-gen script, and that I must set up some sort of database that I then use to bind my backing bean to with the Seam/EJB integration.
Do I *HAVE* to use the @Entity annotation in my backing bean and use the Seam/EJB integration if I'm going to use Seam to manage my beans or do I have to stick with declaring them in my faces-config.xml file and let JSF manage them?
Any help is appreciated!