I have two classes of managed beans and use #ManagedProperty to try to access the second one but I get NullPointerException every time. What is the problem here?
#ManagedBean
#SessionScoped
public class EventCreateEditModel implements Serializable {
#ManagedProperty("#{eventCreateEditCostModel}")
private EventCreateEditCostModel eventCreateEditCostModel;
public void update() {
eventCreateEditCostModel.update();
}
public void setEventCreateEditCostModel(final EventCreateEditCostModel eventCreateEditCostModel) {
this.eventCreateEditCostModel = eventCreateEditCostModel;
}
public EventCreateEditCostModel getEventCreateEditCostModel() {
return eventCreateEditCostModel;
}
}
Here is my second class.
#ManagedBean
#SessionScoped
public class EventCreateEditCostModel implements Serializable {
public void update() {
System.out.println("IT works");
}
}
I try to get the first class to call the second class update using #ManagedProperty but all I get is NullPointerException, when I try to access the update from the first class. I do have setters and getters for the #ManagedProperty.
Here is the stack trace which points to the update method in class EventCreateEditModel (tried to paste the whole stack but this system will not format it so here are the key parts)
`Dec 24, 2015 2:02:57 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: java.lang.NullPointerException
javax.el.ELException: java.lang.NullPointerException
at com.sun.el.parser.AstValue.invoke(AstValue.java:238)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
Caused by: java.lang.NullPointerException
at com.rem40.controller.EventCreateEditModel.update (EventCreateEditModel.java:116)
... 35 more
Dec 24, 2015 2:02:57 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
SEVERE: java.lang.NullPointerException
at com.rem40.controller.EventCreateEditModel.update(EventCreateEditModel.java:116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)`
Related
Using Payara Server 4.1.2.174 with mojarra 2.2.15.
I have a simple Named Bean with scope javax.faces.view.ViewScoped.
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named
#ViewScoped
public class SimpleBean implements Serializable
{
private final Logger logger = Logger.getLogger(SimpleBean.class.getName());
#PostConstruct
private void init()
{
logger.log(Level.SEVERE, "{0}.init()", this);
}
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String action()
{
logger.log(Level.SEVERE, "{0}.action()", this);
logger.log(Level.SEVERE,"====================");
logger.log(Level.SEVERE, "name: {0}", getName());
logger.log(Level.SEVERE,"====================");
return "submit";
}
}
So I have a simple index.xhtml page with form.
<h:form>
<h:inputText value="#{simpleBean.name}"></h:inputText>
<h:link value="To submit" outcome="submit"/>
<h:commandButton value="Welcome Me" action="#{simpleBean.action()}"/>
</h:form>
I can open index.xhtml in two different browser tabs or windows. So, I have the following log:
Severe: solvo.ee.beans.SimpleBean#2adafd68.init()
Finest: Handling PostConstructViewMapEvent
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying #viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean#2adafd68}
Severe: solvo.ee.beans.SimpleBean#49a86248.init()
Finest: Handling PostConstructViewMapEvent
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying #viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean#49a86248}
As we can see there are two different instances of SimpleBean. After that I submit the form of the first tab.
Severe: solvo.ee.beans.SimpleBean#2adafd68.action()
Severe: ====================
Severe: name: First tab
Severe: ====================
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying #viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean#2adafd68}
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying #viewscoped beans from view map: {}
If I try to submit form of the second tab the stored earlier instance of SimpleBean (solvo.ee.beans.SimpleBean#49a86248) won't be used, instead the ViewScopeContextManager will create a new instance of SimpleBean class, as we can see in log:
Severe: solvo.ee.beans.SimpleBean#4797f115.init()
Severe: solvo.ee.beans.SimpleBean#4797f115.action()
Severe: ====================
Severe: name: Second tab
Severe: ====================
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying #viewscoped beans from view map: {simpleBean=solvo.ee.beans.SimpleBean#4797f115}
Finest: Handling PreDestroyViewMapEvent
Finest: Destroying #viewscoped beans from view map: {}
I have checked the code of the com.sun.faces.application.view.ViewScopeContextManager.copyViewScopeContextsFromSession method and as I understand this behavior is normal.
However If i store request parameters or another important data in my bean I will loose it because the instance will be lost after submitting the first form.
Is there a solution to keep bean associated with the second tab primarily (in my example solvo.ee.beans.SimpleBean#49a86248)?
It seems this is a bug with Mojarra and will be fixed in 2.3.10 according to this post: https://github.com/eclipse-ee4j/mojarra/issues/4509#issuecomment-453188481
From the same thread, it looks like Payara have applied the patched without waiting for the 2.3.10 release. Does upgrading to the patched Payara solve the problem for you?
Sorry for my english, I've a war project with cdi 1.0, deltaspike 0.5 and primefaces 4.0, when I'm trying to use #Respository with #EntityManagerConfig because I've two produces for entityManager with diferent #Qualifiers, I'm using glassfish 4 for application server this is de code for Repository, Produces and EntityManagerResolver:
Repository:
#Repository(forEntity = User.class)
#EntityManagerConfig(entityManagerResolver = HbsWebEntityManagerResolver.class, flushMode = FlushModeType.AUTO)
public abstract class UserRepository extends
AbstractEntityRepository<User, Integer> {
#Query(named = User.BY_LOGIN)
public abstract User findByLoginEqual(#QueryParam("login") String login);
}
EntityManagerResolver:
public class HbsWebEntityManagerResolver implements EntityManagerResolver{
#Inject
#HbsWeb
private EntityManager hbsWebEntityManager;
#Override
public EntityManager resolveEntityManager() {
return hbsWebEntityManager;
}
}
Produces:
#ApplicationScoped
public class EntityManagerProducer {
#PersistenceUnit(unitName="HBS")
private EntityManagerFactory hbsEntityManager;
#PersistenceUnit(unitName="HBSWEB")
private EntityManagerFactory hbsWebEntityManager;
#Produces
#Hbs
protected EntityManager createHbsEntityManager() {
return hbsEntityManager.createEntityManager();
}
protected void closeHbsEntityManager(
#Disposes #Hbs EntityManager entityManager) {
if (entityManager.isOpen()) {
entityManager.close();
}
}
#Produces
#HbsWeb
protected EntityManager createHbsWebEntityManager() {
return hbsWebEntityManager.createEntityManager();
}
protected void closeHbsWebEntityManager(
#Disposes #HbsWeb EntityManager entityManager) {
if (entityManager.isOpen()) {
entityManager.close();
}
}
}
When I try to use the repository with #inject I get the follow error:
org.apache.deltaspike.data.impl.handler.QueryInvocationException: Exception calling Repository: [Repository=class co.com.compuhelmac.hbs.repository.UserRepository_$$_javassist_0,method=findByLoginEqual],exception=class org.jboss.weld.exceptions.AmbiguousResolutionException,message=WELD-001318 Cannot resolve an ambiguous dependency between [Producer Method [EntityManager] with qualifiers [#Hbs #Any] declared as [[BackedAnnotatedMethod] #Produces #Hbs protected co.com.compuhelmac.hbs.database.EntityManagerProducer.createHbsEntityManager()], Producer Method [EntityManager] with qualifiers [#HbsWeb #Any] declared as [[BackedAnnotatedMethod] #Produces #HbsWeb protected co.com.compuhelmac.hbs.database.EntityManagerProducer.createHbsWebEntityManager()]]
at org.apache.deltaspike.data.impl.handler.QueryHandler.invoke(QueryHandler.java:86)
at org.apache.deltaspike.partialbean.impl.PartialBeanAbstractMethodHandler.invoke(PartialBeanAbstractMethodHandler.java:44)
at org.apache.deltaspike.partialbean.impl.MethodHandlerProxy.invoke(MethodHandlerProxy.java:35)
at com.sun.proxy.$Proxy549.invoke(Unknown Source)
at co.com.compuhelmac.hbs.repository.UserRepository_$$_javassist_0.findByLoginEqual(UserRepository_$$_javassist_0.java)
at co.com.compuhelmac.hbs.security.HbsLoginEJB.login(HbsLoginEJB.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4695)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:630)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:582)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Caused by: org.jboss.weld.exceptions.AmbiguousResolutionException: WELD-001318 Cannot resolve an ambiguous dependency between [Producer Method [EntityManager] with qualifiers [#Hbs #Any] declared as [[BackedAnnotatedMethod] #Produces #Hbs protected co.com.compuhelmac.hbs.database.EntityManagerProducer.createHbsEntityManager()], Producer Method [EntityManager] with qualifiers [#HbsWeb #Any] declared as [[BackedAnnotatedMethod] #Produces #HbsWeb protected co.com.compuhelmac.hbs.database.EntityManagerProducer.createHbsWebEntityManager()]]
at org.jboss.weld.manager.BeanManagerImpl.resolve(BeanManagerImpl.java:1154)
at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:798)
at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:79)
at org.apache.deltaspike.data.impl.handler.EntityManagerLookup.lookupFor(EntityManagerLookup.java:51)
at org.apache.deltaspike.data.impl.handler.QueryHandler.createContext(QueryHandler.java:97)
at org.apache.deltaspike.data.impl.handler.QueryHandler.invoke(QueryHandler.java:74)
Does anyone know why this error happens?
Going by your stacktrace
org.apache.deltaspike.data.impl.handler.EntityManagerLookup.lookupFor(EntityManagerLookup.java:51)
and taking a look at the sources of DeltaSpike 0.5, I'd say this is a bug in the 0.5 release, since the EntityManager obtained from the EntityManagerResolver is never used.
Try again with a DeltaSpike 0.6-SNAPSHOT - there are many improvements in the Data module, and this particular piece of code looks more correct now.
Your EM resolver is getting called, but the problem is when trying to inject to
#Inject
#HbsWeb
private EntityManager hbsWebEntityManager;
Due to a resolution problem between : createHbsWebEntityManager() and createHbsEntityManager()
How are the #HbsWeb and #Hbs defined? are they related?
I'm trying to use ManagedProperty:
From here
#ManagedBean(name = "SelectionBean")
#SessionScoped
public class TableSelectionBean implements Serializable {
private String selectionMode = "single";
private Collection<Object> selection;
private List<MonitoringData> monitoringData;
private List<MonitoringData> selectionMonitoringData;
to here:
#ManagedBean(name="ActionBean")
#SessionScoped
public class MonitoringActionBean implements Serializable {
private ThreadPoolExecutor executor;
#ManagedProperty(value="{SelectionBean.selectionMonitoringData}")
private List<MonitoringData> selectedMonitoring;
and i got the following error message:
com.sun.faces.mgbean.ManagedBeanCreationException: Unable to set property selectedMonitoring for managed bean ActionBean
...
Caused by: java.lang.IllegalArgumentException: Cannot convert {SelectionBean.selectionMonitoringData} of type class java.lang.String to interface java.util.List
Any idea why it is not working?
It seems you're forgetting the hashtag:
#ManagedProperty(value="{SelectionBean.selectionMonitoringData}")
Should be:
#ManagedProperty(value="#{SelectionBean.selectionMonitoringData}")
I've an EJB service.
#Stateless
public class SomeService {}
I'd like to inject this in a viewscoped bean and initialize with it:
#ManagedBean
#ViewScoped
public class ViewBean implements Serializable {
#EJB
private SomeService someService;
public ViewBean() {
System.out.println(someService.getEntity());
}
}
However, it throws the following exception:
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.example.ViewBean.
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:193)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
[snip]
Caused by: java.lang.NullPointerException
at com.example.ViewBean.<init>(ViewBean.java:42)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at java.lang.Class.newInstance0(Class.java:374)
at java.lang.Class.newInstance(Class.java:327)
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:188)
... 62 more
How is this caused and how can I solve it?
In other words, you're expecting that EJB injection works under the covers as follows:
ViewBean viewBean;
viewBean.someService = new SomeService(); // EJB injected, so that constructor can access it.
viewBean = new ViewBean(); // ViewBean constructed.
However, this is technically impossible. It's not possible to assign an instance variable when the instance isn't been constructed at all.
The canonical approach to perform a task based on injected dependencies directly after construction is to use a #PostConstruct annotated method.
So, to fix your concrete problem, just replace
public ViewBean() {
by
#PostConstruct
public void init() { // Note: Method name is fully free to your choice.
This way the process would under the covers be roughly as follows:
ViewBean viewBean;
viewBean = new ViewBean(); // ShiftBean constructed.
viewBean.someService = new SomeService(); // EJB injected.
viewBean.init(); // PostConstruct invoked.
Please note that the concrete problem has completely nothing to do with the view scope. You'd have had exactly the same problem when using a request, session or application scoped bean. This is thus another evidence that you have never actually excluded it from being the cause by testing using a different scope.
I've a session scoped bean:
#Named
#SessionScoped
public class SessionBean implements Serializable {
private String someProperty;
public String getSomeProperty() {
return someProperty;
}
}
I'd like to inject this in a request scoped bean and initialize with it:
#Named
#RequestScoped
public class RequestBean {
#Inject
private SessionBean sessionBean;
public RequestBean() {
System.out.println(sessionBean.getProperty());
}
}
However, it throws the following exception:
java.lang.NullPointerException
at com.example.RequestBean.<init>(RequestBean.java:42)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.jboss.weld.introspector.jlr.WeldConstructorImpl.newInstance(WeldConstructorImpl.java:206)
at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:117)
at org.jboss.weld.bean.ManagedBean.createInstance(ManagedBean.java:336)
at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.produce(ManagedBean.java:200)
at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:292)
...
How is this caused and how can I solve it?
You're expecting that the injected dependency is available before the bean is constructed. You're expecting that it works like this:
RequestBean requestBean;
requestBean.sessionBean = sessionBean; // Injection.
requestBean = new RequestBean(); // Constructor invoked.
This is however not true and technically impossible. The dependencies are injected after construction.
RequestBean requestBean;
requestBean = new RequestBean(); // Constructor invoked.
requestBean.sessionBean = sessionBean; // Injection.
You should be using a #PostConstruct method instead if you intend to perform business logic based on injected dependencies directly after bean's construction.
Remove the constructor and add this method:
#PostConstruct
public void init() {
System.out.println(sessionBean.getSomeProperty());
}
BalusC's reply is correct, but is does reflect the assignment phase of a object creation, that did not run at this time. But anyway the CDI bean should be accessible if you grep it programatically via:
javax.enterprise.inject.spi.CDI.current().select(SessionBean.class).get()