I'm using JBoss EAP 6.4 (and Weld 1.1.28) and trying to get rid of Seam 2. One part of that is switching over to CDI. I get the following (anonymized) error:
org.jboss.weld.exceptions.DeploymentException: WELD-001443 Pseudo scoped bean
has circular dependencies. Dependency path
[Managed Bean [A] with qualifiers [#Default #Any #Named],
Managed Bean [B] with qualifiers [#Default #Any],
Managed Bean [C] with qualifiers [#Default #Any],
Managed Bean [D] with qualifiers [#Default #Any],
Managed Bean [C] with qualifiers [#Default #Any]]
Every single one of these is #SessionScoped, however, so it seems like this should work since #SessionScoped is a "normal" scope. Why doesn't this work?
#SessionScoped for CDI is javax.enterprise.context.SessionScoped. If you happen to annotate class with javax.faces.bean.SessionScoped then your class is not managed by CDI. When you try to #Inject it then it will be #Dependent pseudo-scoped.
Related
I have the following UserView class:
#ManagedBean(name="usersView", eager=true)
#ApplicationScoped
public class UserView
{
...
public void setUsers(...)
{
...
}
}
I then have another class, UserService which tries to access this bean and then call this method, as follows:
UserView usersView = (UserView) FacesContext.getCurrentInstance().getExternalContext().getSessionMap("usersView");
usersView.setUsers(...)
My issue is, is that usersView keeps coming back as null and hence the method cannot be called.
My end goal is to use this data in a PrimeFaces datatable, like so:
<p:dataTable var="user" value="#{usersView.users}" ...>
I have also tried changing the scope to SessionScoped, but it is still null and I cannot figure out why.
Any suggestions would be greatly appreciated.
The getExternalContext().getXxxMap().get("beanName") approach won't autocreate beans if they don't exist yet. Managed beans will only be autocreated when an EL expression referencing the bean is evaluated. Accessing the scope map doesn't do that. For that, use #ManagedProperty in the source bean instead. You can specify an EL expression in its value.
#ManagedProperty("#{userView}")
private UserView userView; // +setter (no getter required).
Note that this only works if the source bean has the same or a narrower scope than the target bean. If that's not the case, consider managing beans using CDI instead of JSF. You can then use #Inject instead of #ManagedProperty (which doesn't require a setter by the way). Moreover, #ManagedBean and friends is deprecated in upcoming JSF 2.3.
As to eager=true, this has only effect on #ApplicationScoped beans. See also the javadoc (emphasis mine).
...
If the value of the eager() attribute is true, and the managed-bean-scope value is "application", the runtime must instantiate this class when the application starts. This instantiation and storing of the instance must happen before any requests are serviced. If eager is unspecified or false, or the managed-bean-scope is something other than "application", the default "lazy" instantiation and scoped storage of the managed bean happens.
...
See also:
How to choose the right bean scope?
Difference between #ManagedProperty and FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("bean")
Get JSF managed bean by name in any Servlet related class
Backing beans (#ManagedBean) or CDI Beans (#Named)?
I'm using GlassFish 3.0.1. I want to know if I can use:
#ManagedBean
#ConversationScoped
Instead of #Named?
#ManagedBean is a JSF annotation while #ConversationScoped is a CDI annotation, I can't think of any valid scenario to combine them.
In general #Named will cover almost all you needs and it make your bean available to EL thus the JSF pages.
I am getting this exception when I try deploying my application to Glassfish Server:
org.jboss.weld.exceptions.DeploymentException: WELD-001409 Ambiguous
dependencies for type [FileReferenceDao] with qualifiers [#Default] at
injection point [[BackedAnnotatedField] #Inject
com.tugay.fup.web.MyUploadedFilesBean.fileReferenceDao]. Possible
dependencies [[Session bean [class
com.tugay.fup.core.dao.FileReferenceDao with qualifiers [#Any
#Default]; local interfaces are [FileReferenceDao], Session bean
[class com.tugay.fup.core.dao.FileReferenceDao with qualifiers [#Any
#Default]; local interfaces are [FileReferenceDao]]]
The interesting part is
Possible dependencies [[Session bean [class
com.tugay.fup.core.dao.FileReferenceDao with qualifiers [#Any
#Default]; local interfaces are [FileReferenceDao], Session bean
[class com.tugay.fup.core.dao.FileReferenceDao with qualifiers [#Any
#Default]; local interfaces are [FileReferenceDao]]]
What is going on in here?
I only have one FileReferenceDao, which has no Interface or anything else. It does not extend any other class. And this is how I use it:
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#RequestScoped
public class MyUploadedFilesBean {
#Inject
FileReferenceDao fileReferenceDao;
Everything was working fine until 15 minutes ago.
I tried mixing JSF Managed beans with CDI beans, it did not work, I rolled - back. Now I am getting this exception.
#Stateless public class FileReferenceDao {
#PersistenceContext(unitName = "Persistence")
EntityManager em;
I'm trying to deal with #javax.faces.bean.ManagedProperty but without success !
I've been following this guide, and it not seems that hard.
But my code simply won't work!
Here's a little snippet
#ManagedBean
#SessionScoped
public class LoginBean {
private User user;
// ...
}
#Named
#RequestScoped
public class MessagesBean {
#ManagedProperty(value = "#{loginBean}")
private LoginBean loginBean;
public String getUser() {
System.err.println(loginBean == null);
return loginBean.getUser().getUsername();
}
// ...
}
This code gives me a NullPointerException, saying that loginBean is null!
Any suggestion?
You are mixing JSF managed beans with CDI beans. Your LoginBean is a JSF managed bean (it has the #ManagedBean annotation). Your MessageBean is a CDI bean (it has the #Named annotation). If you changed the Message bean to a JSF managed bean (replacing #Named with #ManagedBean) then the problem should be solved (It should work with two CDI beans as well). Or if you're using JSF 2.3 or newer, then use javax.faces.annotation.ManagedProperty instead in the CDI bean.
Here is a short overview of how injection works between both bean types:
CDI #Named --> CDI #Named (works)
CDI #Named --> JSF #ManagedBean (works only if scope of injected bean is broader)
JSF #ManagedBean --> JSF #ManagedBean (works only if scope of injected bean is broader)
JSF #ManagedBean --> CDI #Named (won't work)
But take care of the scope import classes. There are different classes for #SessionScoped and #RequestScoped depending on the bean type.
javax.faces.bean.SessionScoped for #ManagedBeans
javax.enterprise.context.SessionScoped for CDI #Named beans
In addition, for #Named (CDI) use #Inject and for #ManagedBean use #ManagedProperty. There is one thing that does not work in CDI. Your #ManagedProperty(value = "#{loginBean}") gets a full bean, but #ManagedProperty(value = "#{loginBean.user}") to get a 'property' of a bean works to. This is not directly possible in CDI with #Inject. See CDI Replacement for #ManagedProperty for a 'solution'
It is possible to access or to get a backing bean property value from another backing bean in JSF?
Yes, it is possible.
You can access another beans in the context by Application#evaluateExpressionGet(). You can also inject a bean as managed property of other bean in faces-config.xml. If you're already on JSF2, you can even use #ManagedProperty annotation like follows:
#ManagedProperty(value="#{bean}")
private Bean bean;