我们正在使用Vaadin 23(23.0.9)和Vaadin -cdi(14.0.0),并且在@RouteScoped组件中有条件观察者的问题(就像在教程中描述的那样):
@RouteScoped
public class ScopedComponent extends Div {
private void onMessage(
@Observes(notifyObserver = IF_EXISTS)
MessageEvent message) {
setText(message.getText());
}
}
我们在Tomcat 9上运行,使用Weld (3.1.9.Final)作为我们的CDI实现。我们目前的问题是,当触发一个在@RouteScoped组件中观察到的事件时,我们会得到以下异常:
. lang。非法状态异常:路由所有者'class XXX'实例在活动导航组件链中不可用:由bean 'YYY'定义的作用域不存在。
我们认为问题是Vaadin CDI 13.0.0 (https://github.com/vaadin/cdi/releases/tag/13.0.0):
当没有活动路由组件存在时,不允许尝试使用@RouteScope。
在我们正在使用的Weld实现中,getReceiverIfExists方法调用RouteScopedContext类中的getContextualStorage()方法。并且在考虑接收观察者之前调用getReceiverIfExists。因此,所有在事件上有观察者的类都试图被接收,因为不是所有的@RouteScoped类都在当前导航链中,所以会抛出上面提到的错误。
Object receiver = getReceiverIfExists(null); //this is where the exception is thrown
if (receiver == null && reception != Reception.IF_EXISTS) {
// creational context is created only if we need it for obtaining receiver
// ObserverInvocationStrategy takes care of creating CC for parameters, if needed
creationalContext = beanManager.createCreationalContext(declaringBean);
receiver = getReceiverIfExists(creationalContext);
}
if (receiver != null) {
sendEvent(event, receiver, creationalContext);
}
我们不太确定,我们做错了什么,或者我们可以做些什么。我们使用的是正确的vadin -cdi和Weld版本吗?
这是当前vaadin-cdi (version 14.0.0)中的一个bug: https://github.com/vaadin/cdi/issues/390
已经合并了一个错误修复:https://github.com/vaadin/cdi/pull/393