I am totally new to JSF and in learning process, and I am having issues to understand whether to use CDI annotations or JSF annotation. At many places (like this), I found that we should always use CDI annotations, but it really doesn't work and my demo application only works when I use JSF annotations.
Below are examples where I am facing issue and my question is - could someone please explain if I am doing something wrong OR if with JSF I have to use JSF annotations and if this is true then I think these post (like this) are wrong. I see that in that post it is also mentioned that if it is JSF version 2.0 or greater without CDI then JSF annotation should be used, I checked my JSF version and it is JavaServer Faces Reference Implementation 2.1.20 Fri Mar 8 05:55:39 PST 2013
, but I don't know whether it is with CDI or not.
Please refer my code snippet in the end.
@javax.faces.bean.ManagedBean v/s @javax.inject.Named
I found that in order to use a managed bean through EL (expression language) syntax - #{}
, managed bean class can either be annotated with @javax.faces.bean.ManagedBean
or with @javax.inject.Named
.
Theoretically either way should work but when I am using CDI annotation then I get below exception:
javax.el.PropertyNotFoundException: //C:/E_Drive/Projects/Workspace/HakerRank/testing/WebContent/greeting.xhtml @21,42 value="#{userNumberBean.userNumber}": Target Unreachable, identifier 'userNumberBean' 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)
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030)
at javax.faces.component.UIInput.validate(UIInput.java:960)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
at javax.faces.component.UIInput.processValidators(UIInput.java:698)
But when I use @javax.faces.bean.ManagedBean
annotation then things work.
@javax.enterprise.context.SessionScoped v/s @javax.faces.bean.SessionScoped
Again, theoretically both should work, but if I use CDI bean then it doesn't bean a session bean and when I refresh my page then I still see ### UserNumberBean Instantiation ...
in the logs (even though can I see that my browser has same JSESSION ID - Cookie: JSESSIONID=a7iC7zNgF3ddWg069Hzny6T3UvgIVrfQ0GYJf8_pzT6Y0TzYAW3c!1544639247
) which suggests that a new bean instance is getting created. However, if I use javax.faces.bean.SessionScoped
then everything works as expected.
greetings.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Guess Number Facelets Application</title>
</h:head>
<h:body>
<h:form>
<h:graphicImage value="#{resource['images:OracleLogo.png']}"
alt="Duke waving his hand" />
<h2>Hi, my name is Duke. I am thinking of a number from
#{userNumberBean.minimum} to #{userNumberBean.maximum}. Can you guess
it?</h2>
<p>
<h:inputText id="userNo" title="Enter a number from 0 to 10:"
value="#{userNumberBean.userNumber}">
<f:validateLongRange minimum="#{userNumberBean.minimum}" maximum="#{userNumberBean.maximum}" />
</h:inputText>
<h:commandButton id="submit" value="Submit" action="response" />
</p>
<h:message showSummary="true" showDetail="false"
style="color: #d20005;
font-family: 'New Century Schoolbook', serif;
font-style: oblique;
text-decoration: overline"
id="errors1" for="userNo" />
</h:form>
</h:body>
</html>
response.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Guess Number Facelets Application</title>
</h:head>
<h:body>
<h:form>
<h:graphicImage value="#{resource['images:OracleLogo.png']}"
alt="Duke waving his hand" />
<h2>
<h:outputText id="result" value="#{userNumberBean.response}" />
</h2>
<h:commandButton id="back" value="Back" action="greeting" />
</h:form>
</h:body>
</html>
UserNumberBean:
import java.io.Serializable;
import java.util.Random;
import javax.inject.Named;
@Named
@javax.enterprise.context.SessionScoped
public class UserNumberBean implements Serializable {
private static final long serialVersionUID = 5443351151396868724L;
Integer randomInt = null;
Integer userNumber = null;
String response = null;
private int maximum = 10;
private int minimum = 0;
{
System.out.println("### UserNumberBean Instantiation ...");
}
static{
System.out.println("### UserNumberBean Static initialization ...");
}
public UserNumberBean() {
Random randomGR = new Random();
randomInt = new Integer(randomGR.nextInt(maximum + 1));
// Print number to server log
System.out.println("Duke's number: " + randomInt);
}
public void setUserNumber(Integer user_number) {
userNumber = user_number;
}
public Integer getUserNumber() {
return userNumber;
}
public String getResponse() {
System.out.println("### userNumber: " + userNumber + " | randomInt: " + randomInt);
if ((userNumber == null) || (userNumber.compareTo(randomInt) != 0)) {
return "Sorry, " + userNumber + " is incorrect.";
} else {
return "Yay! You got it!";
}
}
public int getMaximum() {
return (this.maximum);
}
public void setMaximum(int maximum) {
this.maximum = maximum;
}
public int getMinimum() {
return (this.minimum);
}
public void setMinimum(int minimum) {
this.minimum = minimum;
}
}
UPDATE 1: @XtremeBiker - I am using Weblogic 12.1.2. Servlet version is 3.0 and JSP version is 2.1, so my JEE version should be >= 6, it means I should have CDI. Now, I don't know how to get the CDI version.