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

发布于 2024-11-07 17:30:40 字数 1098 浏览 6 评论 0原文

我有一个 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 beans - 我已经尝试将注释更改为 @Stateless 和 @Stateful,并且遇到了同样的问题。

在我看来,这可能是 Weld 中的一个错误,也许 Weld 和 EJB 正在争论如何代理该方法 - 大概 EJB 需要添加一个拦截器类并包装该方法以确保线程安全,而 Weld 正在尝试做一些事情要不然让事件监听器工作?

我是否误解了这里的某些内容,CDI 事件处理程序是否应该根本不用于 EJB(在这种情况下,glassfish 应该有更好的错误消息) - 或者这实际上只是 CDI 或 EJB 实现中的一个错误?

I have a Singleton EJB (javax.ejb.Singleton version. sigh.) which has a CDI observer method on it. When I try to deploy this to glassfish 3.1 the server fails to deploy the EAR file without any real explanation - simply saying there was an exception during deployment without any more details.

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

This is the CDI event listener :

public void updateFromGranule(@Observes @CloudMask GranuleAvailableEvent granuleEvent) {
    LOG.info("updating cloud map");
    update(granuleEvent.getGranule(), CloudMask.class);
    fireUpdate();
}

If I change the Singleton bean to just be an @ApplicationScoped bean the app deploys fine. Similarly, if I remove the CDI event observer method the application deploys fine.
I actually need the class to be an EJB singleton because I want the transaction, thread safety etc. of EJBs, so just leaving this as a @ApplicationScoped POJO isn't much use to me. The problem doesn't seem to be limited to Singleton beans though - I've experimented by changing the annotation to @Stateless and @Stateful and I get the same issue.

It seems to me that this might be a bug in Weld, perhaps Weld and EJB are fighting about how they proxy that method - presumably EJB needs to add an interceptor class and wrap that method to ensure thread safety, and Weld is trying to do something else to make the event listener work?

Am I misunderstanding something here, and should CDI event handlers simply not be used on EJBs (in which case there should be better error messages from glassfish) - or is this actually just a bug in the CDI or EJB implementation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怪我闹别瞎闹 2024-11-14 17:30:40

我认为这就是答案:

如果 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

由于某种原因,glassfish 在加载我的 EAR 文件时没有正确报告此异常,只是在加载时显示 Exception应用程序

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

I think this is the answer :

CDI observer methods must apparently either be static or declared in the local interface of an EJB if the EJB declares a local interface. Normally if you try to declare an observer method that isn't in the local interface you get an exception from Weld like this :

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

For some reason glassfish does not report this exception properly when loading my EAR file and simply says Exception while loading the app.

Adding the method to the local interface (or removing the interface declaration on the class) fixes the problem and allows the application to load normally.

情释 2024-11-14 17:30:40

我注意到最新版本的焊接也存在同样的问题。但如果添加 @LocalBean 注释,它将与 @Singleton 和 @Singleton @Startup 一起使用。

I noticed the same problem with the latest version of weld. But if you add the @LocalBean annotation it will work with @Singleton and @Singleton @Startup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文