CDI事件观察方法与EJB兼容吗?

10

我有一个单例EJB(javax.ejb.Singleton版本),它上面有一个CDI观察器方法。当我尝试将其部署到Glassfish 3.1时,服务器在没有任何真正解释的情况下无法部署EAR文件 - 只是说在部署过程中发生了异常,没有更多的细节。

SEVERE: Exception while loading the app
SEVERE: Exception while shutting down application container
....
SEVERE: Exception while shutting down application container : java.lang.NullPointerException

这是CDI事件监听器:

public void updateFromGranule(@Observes @CloudMask GranuleAvailableEvent granuleEvent) {
    LOG.info("updating cloud map");
    update(granuleEvent.getGranule(), CloudMask.class);
    fireUpdate();
}
如果我将单例Bean更改为@ApplicationScoped bean,则应用程序可以成功部署。同样,如果我删除CDI事件观察器方法,应用程序也可以成功部署。 实际上,我需要将该类作为EJB单例,因为我想要EJB的事务、线程安全等功能,所以将其保留为@ApplicationScoped POJO对我来说没有什么用处。但问题似乎不仅限于单例Bean——我已经尝试将注释更改为@Stateless和@Stateful,但出现了相同的问题。
看起来这可能是Weld中的一个错误,也许Weld和EJB正在争夺如何代理该方法——可能EJB需要添加拦截器类并包装该方法以确保线程安全,而Weld正在尝试做其他事情,以使事件监听器正常工作?
我是否存在误解?在EJB上是否应该简单地不使用CDI事件处理程序(在这种情况下,glassfish应该提供更好的错误消息),或者这实际上只是CDI或EJB实现中的一个bug?
2个回答

9
我认为这就是答案:
CDI观察者方法显然必须是静态的,或者在EJB的本地接口中声明,如果EJB声明了本地接口。通常,如果您尝试声明不在本地接口中的观察者方法,则会从Weld中获得异常,如下所示:
org.jboss.weld.exceptions.DefinitionException: WELD-000088 Observer method must be static or local business method:  [method] public org.stain.ObserverBean.testMethod(EventClass) on public@Singleton class org.stain.ObserverBean

由于某些原因,当加载我的EAR文件时,GlassFish未能正确报告这个异常,只是简单地显示“在加载应用程序时出现异常”。

将该方法添加到本地接口中(或删除类上的接口声明)可以解决问题,并允许应用程序正常加载。


7

我注意到最新版本的Weld也存在同样的问题。但是如果你添加@LocalBean注解,它将可以与@Singleton和@Singleton @Startup一起使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接