I'm working on a project in Java EE with JSF and Primefaces. I'm also using Hibernate as a ORM framework. As I see it, Primefaces and Hibernate doesn't interfere, but I mention it so you can get the full picture. I have a login and a register page. Both are Facelets Template Clients and you navigate from the first to the second. The register page is linked to 2 Managed Bean's properties and call a method from the first one. An MCVE would be:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<body>
<ui:composition template="./templates/mainTemplate.xhtml">
<ui:define name="top"></ui:define>
<ui:define name="content">
<h:form>
<h2>Login</h2>
<h:panelGrid columns="2">
<h:outputLabel for="user" value="User:" />
<p:inputText id="user"/>
<h:outputLabel for="password" value="Password:" />
<p:password id="password"/>
<!-- Still no connection to the Login's MB -->
<p:commandButton value="Login"/>
<!-- Go to register.xhtml -->
<p:commandButton value="Register" action="register"/>
</h:panelGrid>
</h:form>
</ui:define>
<ui:define name="bottom">bottom</ui:define>
</ui:composition>
</body>
</html>
<!--ui:composition nested in html and body as in index.xhtml-->
<ui:composition template="./templates/mainTemplate.xhtml">
<ui:define name="top"></ui:define>
<ui:define name="content">
<h:form id="frmRegister">
<h:panelGrid columns="2">
<h:outputLabel for="name" value="Name:" />
<p:inputText id="name" label="Name" required="true" size="50"
value="#{personBean.person.name}"/>
<h:outputLabel for="birthdate" value="Date of birth:" />
<p:calendar id="birthdate"
label="Date of birth"
placeholder="dd/mm/aaaa"
required="true"
value="#{personBean.person.birthdate}"/>
<h:outputLabel for="password" value="Password(*):"/>
<p:password id="password" label="Password" required="true" size="30"
value="#{userBean.user.password}"/>
<h:outputLabel for="password-repeat" value="Repeat your password(*):"/>
<p:password id="password-repeat" label="Repeated password" required="true" size="30"
value="#{userBean.repeatPassword}"/>
<p:commandButton value="Register User" actionListener="#{personBean.addPerson()}"/>
<p:commandButton value="Back" action="index" />
</h:panelGrid>
</h:form>
</ui:define>
<ui:define name="bottom">bottom</ui:define>
</ui:composition>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<h:outputStylesheet name="./css/default.css"/>
<h:outputStylesheet name="./css/cssLayout.css"/>
<h:outputStylesheet name="./css/libs/bootstrap.min.css"/>
<h:outputStylesheet name="./css/libs/bootstrap-theme.min.css"/>
<title>Title</title>
</h:head>
<h:body>
<div id="top">
<ui:insert name="top">Top</ui:insert>
<h1>A Test</h1>
</div>
<div id="content" class="center_content">
<ui:insert name="content">Content</ui:insert>
</div>
<div id="bottom">
<ui:insert name="bottom">Bottom</ui:insert>
</div>
The problem is that when I try to load the page I get a blank page and when I open the Chrome's developers tools I can see that the body is rendered with the same info that the head. To get the picture:
<head>
<link type="text/css" rel="stylesheet" href=".../theme.css?ln=primefaces-bootstrap">
...
<script type="text/javascript" src="...jquery.js?ln=primefaces&v=5.0"></script>
...
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>THE TITLE</title>
<link rel="icon" href="resources/img/favicon.ico">
</head>
<body>
<link type="text/css" rel="stylesheet" href=".../theme.css?ln=primefaces-bootstrap">
...
<script type="text/javascript" src="...jquery.js?ln=primefaces&v=5.0"></script>
...
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>THE TITLE</title>
<link rel="icon" href="resources/img/favicon.ico">
<div id="textarea_simulator" style="position: absolute; top: 0px; left: 0px; visibility: hidden;"></div>
</body>
And the console gives me the following error:
[Warning] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
[Error] Uncaught TypeError: Cannot read property 'debug' of undefined
As you can see, it's the same thing, except for the <div id="textarea_simulator">
element. When I quit the references to the MB's person properties, the pages works fine (I mean delete the value=#{}
in the <p:inputText />
element).
According to the video tutorial suggested in the JSF wiki, and to the Java EE documentation (ch 8.4 Using Facelets Template, p. 136), when you have a ui:composition
tag (which is a Facelets Template Client), everything outside is ignored. Because of that, I tried putting the XML namespace definition within this tag for index
and register
, but the result is the same.
My Managed Beans are as follow:
@ManagedBean
@RequestScoped
public class PersonBean {
@ManagedProperty("#{userBean}")
private UserBean userBean;
private Person person;
//Empty constructor, getter/setter
public void addPerson(){
//In a try/catch block: open connection, make query with prepared statement and commit
}
}
@ManagedBean
@RequestScoped
public class UserBean {
private User user;
private String repeatPassword;
//Constructor, getters and setters
}
Finally, Person
and User
are POJO's with properties, getters and setters (no constructor) Am I missing something? What is my mistake?
I'm working with Netbeans 8.0.2 and with Glasfish Sever 4.1. Any help is very appreciated. Thanks in advance.
The Glassfish server gives me the following message:
SEVERE: JSF cannot create the managed bean personBean when it is required. Following errors have been found:
- The property userBean does not exists for the managed bean personBean
(I am translating from the spanish, so the message may differ from the one you can get). I changed @ManagedProperty("#{userBean}")
for @ManagedProperty("#{UserBean}")
(uppercase) but the result is the same.
Got it. Instead of using @ManagedProperty
annotation
import javax.faces.bean.ManagedProperty;
...
@ManagedProperty("#{userBean}")
private UserBean userBean;
I used the @Inject
annotation
import javax.inject.Inject;
...
@Inject private UserBean userBean;
And now renders perfectly. The solution came out from the The Java EE Tutorial, Release 7, chapter 23.7.- Injecting Beans, page 23.6 (400).
I've seen other tutorials/examples using @ManagedProperty
and working fine, but for some reason doesn't work here. In fact, I searched in the mentioned tutorial and there is NO REFERENCE to @ManagedProperty
, but it is documented in the Java EE API.
I've just find a very good discussion on this subject in this post