我有一个Singleton 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();
}
如果我将Singleton bean更改为@ApplicationScoped bean,则应用程序可以正常部署。同样,如果我删除CDI事件观察器方法,应用程序部署正常。 我实际上需要将该类作为EJB单例,因为我想要EJB的事务,线程安全等,所以将它作为@ApplicationScoped POJO留下来对我来说并没有多大用处。这个问题似乎并不局限于Singleton bean - 我已经通过将注释更改为@Stateless和@Stateful进行了实验,我得到了相同的问题。
在我看来,这可能是Weld中的一个错误,也许Weld和EJB正在争论他们如何代理该方法 - 可能是EJB需要添加一个拦截器类并包装该方法以确保线程安全,而Weld正在尝试做其他事情以使事件监听器工作?
我在这里误解了什么,CDI事件处理程序是否应该在EJB上使用(在这种情况下应该有来自glassfish的更好的错误消息) - 或者这实际上只是CDI或EJB实现中的错误?
答案 0 :(得分:6)
我认为这就是答案:
如果EJB声明了本地接口,那么CDI观察者方法显然必须是静态的,或者在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没有正确报告此异常,只是说Exception while loading the app
。
将方法添加到本地接口(或删除类上的接口声明)可以解决问题并允许应用程序正常加载。
答案 1 :(得分:3)
我注意到最新版焊缝存在同样的问题。但是如果添加@LocalBean注释,它将与@Singleton和@Singleton @Startup一起使用。