Ejb返回java.lang.NullPointerException

时间:2013-11-22 07:37:44

标签: java java-ee glassfish ejb

我是cdi的新手,这是我的第一步。 我在ejb模块中有一个bean:

@Stateless
public class TestBean {
    public String getIt(){
        return "test";
    }
}

我在战争模块中有一个POJO(我试过@EJB和@Inject - 相同的结果)

public class SaveAction  extends Action{
    @EJB    
    private TestBean bean;

    @Override
    public void execute(){
    ....    
    String test = bean.getIt(); //HERE I GET java.lang.NullPointerException
    ...
    }
}

战争和ejb都在耳内。在日志中我看到

  

EJB5181:EJB TestBean的可移植JNDI名称:   【JAVA:全球/ example.com /我的EJB / testBean就com.example.TestBean,   的java:全球/ example.com /我的EJB / testBean这个]]]

由此我得出结论bean被初始化 - 但我找不到它。我做错了什么?

1 个答案:

答案 0 :(得分:3)

CDI和其他依赖注入容器不使用魔法!它只是普通的java代码,它不能比任何其他任何地方编写的java代码做得更多或更少。因此,当通过new直接实例化对象时,框架不可能进行注入:

SaveAction action = new SaveAction();
// don't expect any injection has happened - it can't! no magic!
// action.bean is still null here!

框架不知道像SaveAction这样的对象已被实例化。 (因此有必要以某种方式告知框架有关新创建的对象 - 但是构造函数和'new'语句都没有这样做!只想一下如何编写这样的框架代码!这是不可能的!*)

要使注入工作,必须由容器创建对象!否则它不受管理! (另见Web Beans specification (JSR 299)的第3.7章)。

执行此操作的最佳方法是让容器将对象注入另一个已管理的bean。这似乎只是解决了这个问题,但是你的应用程序中有一些已经托管的bean,比如servlet!

建议:让您的SaveAction CDI识别(例如用@Default注释)并将其注入您的servlet!

教程:


*)从理论上讲,应该可以使用面向方面的编程或检测来操作bean的构造函数,以便在调用它们时通知容器。但这是一个非常复杂的概念,我认为有许多未解决的问题。