Asynchronous 带有Vaadin的EJB异步线程,注入不工作(Vaadin 8,Vaadin CDI,EJB ManagedExecutorService线程)
我是Vaadin框架和JavaEE的新手。 我正在使用VaadinFramework8.1.6,VaadinCDI插件2.0.0,运行在Tomee7.0.2服务器上。 我正在尝试使用EJB管理的线程池(ManagedExecutorService)进行异步/后台数据加载。 我在使用注射的豆子时遇到问题 所有注入的bean都可以在单线程UI中正常工作。当我想在后台线程中使用一些注入bean时,其中一些bean无法访问 Vaadin CDI用户界面Asynchronous 带有Vaadin的EJB异步线程,注入不工作(Vaadin 8,Vaadin CDI,EJB ManagedExecutorService线程),asynchronous,ejb,vaadin,cdi,vaadin8,Asynchronous,Ejb,Vaadin,Cdi,Vaadin8,我是Vaadin框架和JavaEE的新手。 我正在使用VaadinFramework8.1.6,VaadinCDI插件2.0.0,运行在Tomee7.0.2服务器上。 我正在尝试使用EJB管理的线程池(ManagedExecutorService)进行异步/后台数据加载。 我在使用注射的豆子时遇到问题 所有注入的bean都可以在单线程UI中正常工作。当我想在后台线程中使用一些注入bean时,其中一些bean无法访问 Vaadin CDI用户界面 @CDIUI("") @Theme("myuith
@CDIUI("")
@Theme("myuitheme")
@Push
public class MyUI extends UI {
// ...
@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinCDIServlet {
}
}
数据服务
@NormalUIScoped
public class DataService {
// consts, functions, ...
public Data getData(String param) {
// call REST service, load, decode and aggregate data
// ...
}
}
MyView
@CDIView(value=MyView.VIEWNAME, supportsParameters=true)
public class MyView extends Panel implements View {
public final static String VIEWNAME = "main";
@Resource
private ManagedExecutorService executor;
@Inject
private MyUI ui;
@Inject
private DataService dataService;
public void fun1() {
System.out.println("fun1, thread_id: " + Thread.currentThread().getId());
Future<Data> dataFuture = executor.submit(() -> loadData(param));
// ...
}
private Data loadData(String param) {
// launched in executor thread
System.out.println("loadData, thread_id: " + Thread.currentThread().getId());
// accessing injected ui works fine, the ui is updated correctly
ui.access(() -> {
clearMyView();
}
// accessing injected dataService doesn't work
// exception: java.lang.IllegalStateException
Data data = dataService.getData(param);
ui.access(() -> {
updateMyView(data);
}
return data;
}
//...
}
@CDIView(value=MyView.VIEWNAME,supportsParameters=true)
公共类MyView扩展面板实现视图{
公共最终静态字符串VIEWNAME=“main”;
@资源
私有ManagedExecutorService执行器;
@注入
私人密室;
@注入
私有数据服务数据服务;
公共图书馆1({
System.out.println(“fun1,thread_id:+thread.currentThread().getId());
Future dataFuture=executor.submit(()->loadData(param));
// ...
}
私有数据加载数据(字符串参数){
//在执行器线程中启动
System.out.println(“loadData,thread_id:+thread.currentThread().getId());
//访问注入的ui工作正常,ui更新正确
ui.access(()->{
clearMyView();
}
//访问注入的数据服务不起作用
//异常:java.lang.IllegalStateException
数据数据=dataService.getData(参数);
ui.access(()->{
更新视图(数据);
}
返回数据;
}
//...
}
日志
fun1,螺纹编号:77
加载数据,线程id:102
例外情况
java.lang.IllegalStateException:无法恢复的会话数据
DataService,WebBeansType:MANAGED,名称:null,API
类型:[xxx.DataService,java.lang.Object],
限定符:[javax.enterprise.inject.Default,javax.enterprise.inject.Any]
在
com.vaadin.cdi.internal.UIScopedContext.getContextualStorage(UIScopedContext.java:68)
在
org.apache.deltaspike.core.util.context.AbstractContext.get(AbstractContext.java:113)
在
com.vaadin.cdi.internal.AbstractVaadinContext.get(AbstractVaadinContext.java:154)
位于com.vaadin.cdi.internal.ContextWrapper.get(ContextWrapper.java:49)
在
org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextAlinstance(NormalScopedBeanInterceptorHandler.java:101)
在
org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.get(NormalScopedBeanInterceptorHandler.java:71)
在
xxx.myui.data.DataService$$OwbNormalScopeProxy0.getData(xxx/myui/data/DataService.java)
位于xxx.myui.view.MyView.loadData(MyView.java:855)
xxx.myui.view.MyView.lambda$27(MyView.java:645)
org.apache.openejb.threads.task.cucalable$1.call(cucalable.java:34)
位于org.apache.openejb.threads.task.CUTask.invoke(CUTask.java:100)
org.apache.openejb.threads.task.CUCallable.call(CUCallable.java:31)
位于java.util.concurrent.FutureTask.run(未知源代码)
位于的java.util.concurrent.ThreadPoolExecutor.runWorker(未知源)
java.util.concurrent.ThreadPoolExecutor$Worker.run(未知源代码)位于
java.lang.Thread.run(未知源)
有什么问题吗?您是否有注释的特定原因
@NormalUIScoped
?如果没有,则此更改有效
// @NormalUIScoped // why is this ?
@UIScoped @Stateful
public class DataService {
...
}
谢谢。这似乎很好。根据Vaadin CDI文档(),我一直在使用
@NormalUIScoped
。@UIScoped
似乎是注入直接bean引用的有限版本,@NormalUIScoped
是“正常的”CDI是一种注入代理对象的方法。但是这个代理在另一个线程中运行时,在查找它的bean时会遇到问题。