问题描述
我已经在网站上查看了与该错误有关的其他问题,但大多数问题与SessionScope有关或未得到解答.唯一可能有用的方法是无活动从线程中调用bean时,作用域类型为javax.enterprise.context.RequestScoped的上下文,但不在我所拥有的上下文中.
I've looked at other questions relating to this error on the site but most of them are either about SessionScope or are unanswered. The only possibly helpful one is No active contexts for scope type javax.enterprise.context.RequestScoped when invoking a bean from a thread but it's not in the context I have.
我正在Wildfly 10.1(Java ee 7)上运行JAX-RS端点.看起来像这样:
I'm running a JAX-RS endpoint on Wildfly 10.1 (Java ee 7). Looks something like this:
@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
是
I added the try-catch only because of this problem, it's not generally there. Order
is
@Stateful
@RequestScoped
public class Order {
private Item item;
// setter and getter
}
Order是RequestScoped的,因为当它被使用/处理时,它经历了一系列的责任链(几个无状态的Bean注入了Order并按顺序对其进行更改).无论如何,问题不在于设计,而在于错误.
Order is RequestScoped because when it's being used/processed it goes through a sort of chain of responsibility (several Stateless beans that inject the Order and change it in sequence). Anyway the question is not about the design but about the error.
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
注释ServerResource类( @Stateless vs @RequestScoped ),但这没关系.
I tried to annotate the ServerResource class with @Stateless
or RequestScope
(@Stateless vs @RequestScoped) but it didn't matter.
为什么会出现此错误,如何使我的代码正常工作?
Why do I get this error and how do I get my code working?
推荐答案
在CDI中,上下文不会传播到其他线程,并且如果您看一看规格,就会发现上下文与线程相关的概念很分散. Bean存储区(用于保存上下文的Bean的地图")是由ThreadLocal
实现的,因此它将无法正常工作.
In CDI, contexts do not propagate to other threads and if you glance at spec, there are scattered notions of contexts being tied to thread. And the Bean stores ("maps" which hold beans for context) are implemented by ThreadLocal
so it just won't work.
无法使用现有上下文解决此问题-唯一的选择是定义自定义范围/上下文,以处理线程之间的上下文传播.
There is no way around this using existing contexts - the only option is to define your custom scope/context which will handle context propagation across threads.
注意,现在有一个 JIRA票证考虑将类似此功能的内容添加到Weld.
Note that there is now a JIRA ticket created which considers adding something like this functionality to Weld.
这篇关于为什么会收到WELD-001303:作用域类型javax.enterprise.context.RequestScoped异常没有活动上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!