java - 更改从不同线程提交到 ManagedExecutorService 的 Runnable 中的 CDI sessionscoped bean 会引发 ContextNotActiveException

标签 java multithreading jakarta-ee cdi

我在 REST 服务中调用了以下方法,需要立即返回:

@Inject
private ScheduleManager scheduleManager;

@Resource(name = "DefaultManagedExecutorService")
ManagedExecutorService executor;

public String solveSchedule(@PathParam("conferenceId") Long conferenceId) {
    executor.submit(new SolverCallable());
    return "Solved started.";
}

它提交这个内部类以在另一个线程上执行

private class SolverCallable implements Runnable {

    public void run() {
        Schedule bestSchedule = ...; // do some long computation
        scheduleManager.setSchedule(bestSchedule); // throws ContextNotActiveException
    }

}

如何使用长计算的结果更改 Runnable 中的 session 作用域 bean?

最佳答案

你不能。即使您传递了引用,该引用也会丢失,因为您获得的只是代理。代理旨在查看 Activity 线程并在这些线程上执行工作。当它到达托管执行程序时,该线程不是原始 HTTP session 的一部分,因此,您会收到 ContextNotActiveException

从技术上讲,JAX-RS 并不能很好地理解 HTTP session ,规范中没有实际要求 JAX-RS 资源参与 HTTP session 。

我向人们推荐的最常见的解决方法是使用一些集中位置来存储这些类型的大型结果,并从那里读取 session 范围的对象。让执行者也与该组件对话。这可能就像一个与 HTTP session ID 无关的 HashMap 一样简单。

要获取 session ID,只需调用 HttpSession.getId()。您还可以通过使用 @SessionScoped bean 之一中的 @PreDestroy 方法来调用中心点并销毁引用来销毁 map 引用。

就线程而言,除了能够从 session 作用域 bean 中注入(inject)对可运行对象的引用(或使可运行对象成为 session 作用域 bean)并告诉它之外,我想不出任何方法来终止它。它从那里停止线程。

@SessionScoped
public class SessionBean implements Runnable,Serializable {

    private HttpSession httpSession;
    @PostConstruct
    public void init() {
        httpSession = CDI.current().select(HttpSession.class).get();
        // register the session
    }
    @Override
    public void run() {

    }

    @PreDestroy
    public void unregister() {
        // unregister the session
        // kill the thread.
    }
}

关于java - 更改从不同线程提交到 ManagedExecutorService 的 Runnable 中的 CDI sessionscoped bean 会引发 ContextNotActiveException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26934461/

相关文章:

Java 7zip 压缩太大

java - 对 Graphics2D 对象进行 HitTest ?

java - Thread 构造函数如何直接接受 run 方法?

java - 过滤器还是什么? -- 进入Spring应用程序之前检查文件

java - 检查 .class 文件中类的包名和类名的工具

java - 如何将 org.apache.tika 源集成到我的项目中?

c# - 使用 "Control.CheckForIllegalCrossThreadCalls = false"是个好主意吗

java - 灵活的倒计时?

java - 设置传入 httpServletRequest 的 cookie 版本

JSF 2.0 和 Facelets