尝试在托管bean构造函数中访问@EJB bean时,NullPointerException [英] NullPointerException while trying to access @EJB bean in managed bean constructor

查看:279
本文介绍了尝试在托管bean构造函数中访问@EJB bean时,NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个EJB服务。

@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() {

by

@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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆