尝试在托管 bean 构造函数中访问 @EJB bean 时出现 NullPointerException [英] NullPointerException while trying to access @EJB bean in managed bean constructor
问题描述
我有一个 EJB 服务.
I've an EJB service.
@Stateless
public class SomeService {}
我想将它注入到一个视图范围的 bean 中并用它进行初始化:
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?
推荐答案
换句话说,您期望 EJB 注入的工作原理如下:
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.
在构造之后直接基于注入的依赖执行任务的规范方法是使用 @PostConstruct
注释方法.
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() {
由
@PostConstruct
public void init() { // Note: Method name is fully free to your choice.
这样的过程大致如下:
ViewBean viewBean;
viewBean = new ViewBean(); // ShiftBean constructed.
viewBean.someService = new SomeService(); // EJB injected.
viewBean.init(); // PostConstruct invoked.
请注意,具体问题与视图范围完全无关.在使用请求、会话或应用程序范围的 bean 时,您会遇到完全相同的问题.因此,这是另一个证据,表明您从未通过使用不同的范围进行测试而将其排除在实际原因之外.
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.
这篇关于尝试在托管 bean 构造函数中访问 @EJB bean 时出现 NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!