Cannot find CDI beans - jsf

I created this simple CDI bean:
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;
#Named("DashboardController")
#ViewScoped
public class Dashboard implements Serializable
{
.......
}
I removed all configuration from faces-config.xml. I created this beans.xml file into WEB-INF directory:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
When I opened the JSF page the bean cannot be found. Can you tell me what am I missing? I don't want to declare the beans into faces-config.xml.
P.S I don't know if this is important or not but this is a WAB package with CDI beans.

You'll need to use ViewAccessScoped instead of ViewScoped.
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped;
//Note the different import
import javax.faces.context.FacesContext;
import javax.inject.Named;
#Named("dashboardController")
#ViewAccessScoped
public class Dashboard implements Serializable
{
.......
}
You should also start the name in Named with a non-capital letter.

You might need to add the faces_config file to your META-INF folder of your WAB as described in this thread
That aside, even if the bean is found, you might still have problems with the scoping; You can't apply a JSF scope to a CDI bean.
CDI's #ConversationScoped is a somewhat less than convenient alternative to JSF's #ViewScoped. The inconvenience of the scope lies in the fact that you need to inject an extra managed object and you have to actively manage the scope yourself. To use:
Annotate your bean with #ConversationScoped
#Named("DashboardController")
#ConversationScoped
public class Dashboard implements Serializable
{
}
Inject the Conversation object into your bean
#Inject
private Conversation conversation;
On this object, you need to call begin() and end() to start the "conversation" (a la viewscope) and "end" the conversation (like JSF does by destroying a viewscoped bean) respectively. This is a matter of design and context. At the very least, you can call conversation.begin() in a #PostConstructor. Where you end the conversation depends on your specific use case

Related

Null when session scoped managed bean taken from session

Here is the managed bean declaration:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "user")
#SessionScoped
public class UserConsoleAction extends UserAction implements Serializable {
And the following code from servlet returns null:
UserConsoleAction uca = (UserConsoleAction) req.getSession().getAttribute("user");
This is an old code written on JSF 1 and now JSF 2.2 is using.
This was working fine & able to get session scoped managed bean from session when managed bean was declared in faces-config.xml.
<managed-bean>
<description>Used for user console functions</description>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>com.web.admin.UserConsoleAction</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
But when I removed this faces-config.xml entry & used ManagedBean annotation, the code to get managed bean instance from session returns null.
What may be the cause for this change since it is only the declaration part changed from xml to annotation.
ManagedBean annotation worked fine when extends UserAction is removed. UserAction is a request scoped bean & UserConsoleAction is session scoped.

JSF init not called on page refresh

I have jsf session scoped bean. Its init method having annotation #PostConstruct is called when the page is loaded for the first time but not on every reload or refresh. I want to call some method on every page refresh. What annotation or change in xhtml file do I need to use
Try change your annotation tag as follows
Just change it to ViewScope. import javax.annotation.PostConstruct;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named
#ViewScoped
public class YourControllerClass implements Serializable {
#PostConstruct
public void init(){
}
}
If you want to call a method on every page refresh it 's better to use ComponentSystemEvent.
You can refer below link
https://www.tutorialspoint.com/jsf/jsf_applicationevents_tag.htm

#SessionScoped cannot be resolved to a type

I am using #SessionScoped in my managed bean and it gives me the error.
#SessionScoped cannot be resolved to a type
What am I missing?
Relevant code:
package javaeetutorial.guessnumber;
import java.io.Serializable;
import java.util.Random;
#Named
#SessionScoped
public class UserNumberBean implements Serializable {
// Do stuff.
}
Add the import below,
import javax.enterprise.context.RequestScoped;
In the future your can always use you IDE to resolve the imports for you, ctrl+shift+o in eclipse.
Hope that helps.
Add the Faces library instead:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

Only First JSF Controller is Created. Others Are Ignored

My first time trying Java and this error is rather strange and I seem to be the only one having the problem on this planet.
I have two web pages:
<h:link outcome="index">Home</h:link>
<h:link outcome="about">About</h:link>
I have two controllers, shown below in the order I created them in package Controller:
HomeController.java
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class HomeController implements Serializable{
public HomeController() {
System.out.println("Home Controller Created......");
}
}
AboutController.java:
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class AboutController implements Serializable{
public AboutController() {
System.out.println("About Controller Created......");
}
}
If I visit home.xhtml, I see Home Controller Created...... but I don't see any message on about.xhtml. The Controller doesn't get called even when I Debug with NetBeans.
Your package declaration is wrong.
Firstly:
Use javax.faces package when playing with JSF, thus your #SessionScope package is wrong.
Secondly:
You need to use #ManagedBean instead of #Named. JSF automatically creates SessionScope bean for you with first reference to it. Don't put anything in constructor because JSF can create the bean when it wants and if the construction fails (Nullpointer etc.) then you have problem. JSF style is to use #PostConstruct annotation to initialise data after construction.
If in your xhtml you have for example <h:outputText value="#{aboutcontroller.someValue}then the AboutBean is created once/session.
(You can also use #ManagedBean(name="aboutController") and reference to it in xhtml with #{aboutController.someValue}
Btw: JSF is all about controllers, usually controllers are in #RequestScope. You can divide your session in those 2 #SessionScope beans, but in the end you only have 1 session. Consider removing the other SessionScope bean, and using #RequestScope beans to manipulate the data in #SessionScope bean. Another good option is to use #ViewScope bean if you are validating some fields and showing error messages with incorrect field values.

Inject CDI bean into JSF #ViewScoped bean

I have a problem with JSF, CDI project. I did a lot of research and I found that in CDI there is no #ViewedScoped annotation. I solving problem with ajax based page with dialog. I want to pass variable to dialog from datatable. For this purpose, I can't use #RequestedScoped bean because value is discard after end of request. Can anyone help me to solve it? I can't use #SessionScoped but it's a bad practice IMHO. Or maybe save only this one variable into session who knows. Can you guys give me any hints how to solve this problem elegantly?
import javax.enterprise.context.ApplicationScoped;
#ApplicationScoped
public class ServiceBean implements Serializable {
...
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class SomeBean {
#Inject
ServiceBean serviceBean;
#Postconstruct ...
Here is the error message:
com.sun.faces.mgbean.ManagedBeanCreationException: An error occurred performing resource injection on managed bean warDetailBean
First, If you are attempting to use CDI, you need to activate it by putting a WEB-INF/beans.xml file in your application (note that this file can be empty), more informations about that file could be found in the Weld - JSR-299 Reference Implementation.
As you are using Tomcat, please be sure to respect all the configuration requirements by following the steps in How to install CDI in Tomcat?
Second, Even if you can use #Inject inside a JSF managed bean, It's preferable that you don't mix JSF managed beans and CDI, please see BalusC's detailed answer regarding Viewscoped JSF and CDI bean.
So if you want to work only with CDI #Named beans, you can use OmniFaces own CDI compatible #ViewScoped:
import javax.inject.Named;
import org.omnifaces.cdi.ViewScoped;
#Named
#ViewScoped
public class SomeBean implements Serializable {
#Inject
ServiceBean serviceBean;
}
Or, if you want to work only with JSF managed beans, you can use #ManagedProperty to inject properties:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class SomeBean{
#ManagedProperty(value = "#{serviceBean}")
ServiceBean serviceBean;
}
See also:
ManagedProperty in CDI #Named bean returns null
Omnifaces CDI ViewScoped

Resources