EJB 异步线程与 Vaadin,注入不工作(Vaadin 8、Vaadin-CDI、EJB ManagedExecutorService 线程)
EJB async thread with Vaadin, inject not working (Vaadin 8, Vaadin-CDI, EJB ManagedExecutorService thread)
我是 Vaadin Framework 和 Java EE 的新手。
我在 TomEE 7.0.2 服务器上使用 Vaadin Framework 8.1.6、Vaadin-CDI 插件 2.0.0、运行。
我正在尝试使用 EJB 托管线程池 (ManagedExecutorService) 进行 asynchronous/background 数据加载。
我在使用一些注入的 bean 时遇到问题。
所有注入的 bean 在单线程中工作正常 UI。当我想在后台线程中使用一些注入的bean时,其中一些无法访问。
Vaadin-CDI UI
@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;
}
//...
}
日志
fun1, thread_id: 77
loadData, thread_id: 102
异常
java.lang.IllegalStateException: Session data not recoverable for
DataService, WebBeansType:MANAGED, Name:null, API
Types:[xxx.DataService,java.lang.Object],
Qualifiers:[javax.enterprise.inject.Default,javax.enterprise.inject.Any]
at
com.vaadin.cdi.internal.UIScopedContext.getContextualStorage(UIScopedContext.java:68)
at
org.apache.deltaspike.core.util.context.AbstractContext.get(AbstractContext.java:113)
at
com.vaadin.cdi.internal.AbstractVaadinContext.get(AbstractVaadinContext.java:154)
at com.vaadin.cdi.internal.ContextWrapper.get(ContextWrapper.java:49)
at
org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:101)
at
org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.get(NormalScopedBeanInterceptorHandler.java:71)
at
xxx.myui.data.DataService$$OwbNormalScopeProxy0.getData(xxx/myui/data/DataService.java)
at xxx.myui.view.MyView.loadData(MyView.java:855) at
xxx.myui.view.MyView.lambda(MyView.java:645) at
org.apache.openejb.threads.task.CUCallable.call(CUCallable.java:34)
at org.apache.openejb.threads.task.CUTask.invoke(CUTask.java:100) at
org.apache.openejb.threads.task.CUCallable.call(CUCallable.java:31)
at java.util.concurrent.FutureTask.run(Unknown Source) at
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at
java.lang.Thread.run(Unknown Source)
怎么了?
您是否有注释的具体原因 @NormalUIScoped
?如果不是,此更改有效
// @NormalUIScoped // why is this ?
@UIScoped @Stateful
public class DataService {
...
}
我是 Vaadin Framework 和 Java EE 的新手。 我在 TomEE 7.0.2 服务器上使用 Vaadin Framework 8.1.6、Vaadin-CDI 插件 2.0.0、运行。 我正在尝试使用 EJB 托管线程池 (ManagedExecutorService) 进行 asynchronous/background 数据加载。 我在使用一些注入的 bean 时遇到问题。
所有注入的 bean 在单线程中工作正常 UI。当我想在后台线程中使用一些注入的bean时,其中一些无法访问。
Vaadin-CDI UI
@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;
}
//...
}
日志
fun1, thread_id: 77
loadData, thread_id: 102
异常
java.lang.IllegalStateException: Session data not recoverable for DataService, WebBeansType:MANAGED, Name:null, API Types:[xxx.DataService,java.lang.Object], Qualifiers:[javax.enterprise.inject.Default,javax.enterprise.inject.Any] at com.vaadin.cdi.internal.UIScopedContext.getContextualStorage(UIScopedContext.java:68) at org.apache.deltaspike.core.util.context.AbstractContext.get(AbstractContext.java:113) at com.vaadin.cdi.internal.AbstractVaadinContext.get(AbstractVaadinContext.java:154) at com.vaadin.cdi.internal.ContextWrapper.get(ContextWrapper.java:49) at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:101) at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.get(NormalScopedBeanInterceptorHandler.java:71) at xxx.myui.data.DataService$$OwbNormalScopeProxy0.getData(xxx/myui/data/DataService.java) at xxx.myui.view.MyView.loadData(MyView.java:855) at xxx.myui.view.MyView.lambda(MyView.java:645) at org.apache.openejb.threads.task.CUCallable.call(CUCallable.java:34) at org.apache.openejb.threads.task.CUTask.invoke(CUTask.java:100) at org.apache.openejb.threads.task.CUCallable.call(CUCallable.java:31) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
怎么了?
您是否有注释的具体原因 @NormalUIScoped
?如果不是,此更改有效
// @NormalUIScoped // why is this ?
@UIScoped @Stateful
public class DataService {
...
}