为什么我会收到一个WELD-001303:对于范围类型javax.enterprise.context.RequestScoped例外没有有效的环境?

问题描述 投票:0回答:2

我看了有关网站上的这个错误的其他问题,但其中大部分都是要么约SessionScope或者无人接听。唯一的可能是有用的一个是No active contexts for scope type javax.enterprise.context.RequestScoped when invoking a bean from a thread但它不是在我的环境。

我跑在Wildfly 10.1(Java EE的7)JAX-RS端点。看起来是这样的:

@Path("")
public class ServerResource {

    @Inject
    Order order;

    @Resource
    ManagedExecutorService mes;

    @PUT
    @Path("/prepareOrder")
    public void prepareOrder(@Suspended AsyncResponse response) {
        mes.execute(() ->  {
            try {
                Item item = new Item(); // JPA entity
                order.setItem(item); // line 71
                // call a service to save the order data (like item) to the DB
            } catch (Exception e) {
                e.printStackTrace();
                response.resume(false);
            }
            response.resume(true);
        });
    }
}

我加在try-catch只有这个问题,因为它不是一般有。 Order

@Stateful
@RequestScoped
public class Order {
    private Item item;
    // setter and getter
}

因为真实使用时它/处理它通过一种责任(即注入顺序和改变它在几个次序无状态bean)的链的顺序RequestScoped。反正这个问题不是关于设计,但有关该错误。

该生产线order.setItem(item);抛出异常:

org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:689)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:90)
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:165)
at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
at com.a.b.Order$Proxy$_$$_WeldClientProxy.setItem(Unknown Source)
at com.a.c.ServerResource.lambda$0(ServerResource.java:71)
at org.jboss.as.ee.concurrent.ControlPointUtils$ControlledRunnable.run(ControlPointUtils.java:105)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.glassfish.enterprise.concurrent.internal.ManagedFutureTask.run(ManagedFutureTask.java:141)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:250)

我试图用注释或@Stateless RequestScope@Stateless vs @RequestScoped)的ServerResource类,但是这并不重要。

为什么会出现这种错误,以及如何让我的代码工作?

jax-rs wildfly cdi
2个回答
3
投票

在CDI,上下文不会传播到其他线程,如果你浏览一下规格,有被捆绑的上下文线程零散的概念。而豆店(“映射”持有上下文豆)由ThreadLocal实现所以它只是将无法工作。

有解决这个使用现有的环境没有办法 - 唯一的选择是定义您的自定义范围/背景下,它将处理跨线程上下文传播。

编辑:请注意,现在是考虑加入这样的功能,焊接产生的JIRA ticket


0
投票

你可以加入的背景之下,我想你理解错了。该服务器有它自己的线程池。因此,每个请求是默认异步(每用户请求创建新线程)。

ContextControl ctxCtrl = (ContextControl) BeanProvider.getContextualReference(ContextControl.class, new Annotation[0]);
ctxCtrl.startContext(RequestScoped.class);
try{
//...
} finally {
 ctxCtrl.stopContext(RequestScoped.class);
}
© www.soinside.com 2019 - 2024. All rights reserved.