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:
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
by
This way the process would under the covers be roughly as follows:
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.