cdi - javax.enterprise.context.ContextNotActiveException 在@Producer 方法中使用作用域 bean
cdi - javax.enterprise.context.ContextNotActiveException while using scoped beans in @Producer methods
我正在使用 Websphere Application Server 8.0.0.5,我在使用 CDI 时发现了以下问题。
- Classes which have
@Producer
methods cannot have any scope other than @Dependent
- Any bean whose scope is other than
@Dependent
cannot be injected and used in classes with @Producer
methods.
在执行上述任何任务时,我得到:
[10/8/15 14:50:30:764 GMT+05:30] 00000019 InjectInjecti E CWOWB0102E: A JCDI error has occurred: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
[10/8/15 14:50:30:766 GMT+05:30] 00000019 BusinessExcep E CNTR0019E: EJB threw an unexpected (non-declared) exception during invocation of method "doSomething". Exception data: javax.ejb.EJBException: Injection failure; nested exception is: javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:321)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:124)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:95)
......
复制问题的示例代码:
public class Producer{
@Inject
@MyQualifier
private Properties properties;
@Produces
public Logger getLogger(InjectionPoint ip){
System.out.println(properties);
System.out.println("Injection point is: "+ip);
return Logger.getLogger(ip.getMember().getDeclaringClass().getName());
}
}
public class AnotherProducer{
@Produces
@MyQualifier
@ApplicationScoped
public Properties getProperties(){
Popperties p = new Properties();
p.put("key","value");
return p;
}
}
我的问题是 - 我是否违反了 CDI 规范或我的容器有问题?
根据 CDI 规范,类型 @ApplicationScoped
的范围应该始终可用 - 通常这意味着此范围内的对象在您的应用程序的生命周期内存在。
但您似乎遇到了 Websphere 中的错误,如 here 中所述。如果你想使用 @ApplicationScoped
个 bean,你有以下选项:
- 切换到不同的应用程序服务器或升级 Websphere,或者至少升级 WebSphere 中的 WebBeans 库(也许
不是你的选择)
- 创建一个 CDI 扩展以添加您的自定义
@ApplicationScoped
范围(可能对某些内容编码过多,应用服务器应该已经支持)
- 不要在您的生产者上使用
@ApplicationScoped
,而是将创建的 bean 缓存在 Singleton bean 中(如果它们是之前创建的)
我正在使用 Websphere Application Server 8.0.0.5,我在使用 CDI 时发现了以下问题。
- Classes which have
@Producer
methods cannot have any scope other than@Dependent
- Any bean whose scope is other than
@Dependent
cannot be injected and used in classes with@Producer
methods.
在执行上述任何任务时,我得到:
[10/8/15 14:50:30:764 GMT+05:30] 00000019 InjectInjecti E CWOWB0102E: A JCDI error has occurred: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
[10/8/15 14:50:30:766 GMT+05:30] 00000019 BusinessExcep E CNTR0019E: EJB threw an unexpected (non-declared) exception during invocation of method "doSomething". Exception data: javax.ejb.EJBException: Injection failure; nested exception is: javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:321)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:124)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:95)
......
复制问题的示例代码:
public class Producer{
@Inject
@MyQualifier
private Properties properties;
@Produces
public Logger getLogger(InjectionPoint ip){
System.out.println(properties);
System.out.println("Injection point is: "+ip);
return Logger.getLogger(ip.getMember().getDeclaringClass().getName());
}
}
public class AnotherProducer{
@Produces
@MyQualifier
@ApplicationScoped
public Properties getProperties(){
Popperties p = new Properties();
p.put("key","value");
return p;
}
}
我的问题是 - 我是否违反了 CDI 规范或我的容器有问题?
根据 CDI 规范,类型 @ApplicationScoped
的范围应该始终可用 - 通常这意味着此范围内的对象在您的应用程序的生命周期内存在。
但您似乎遇到了 Websphere 中的错误,如 here 中所述。如果你想使用 @ApplicationScoped
个 bean,你有以下选项:
- 切换到不同的应用程序服务器或升级 Websphere,或者至少升级 WebSphere 中的 WebBeans 库(也许 不是你的选择)
- 创建一个 CDI 扩展以添加您的自定义
@ApplicationScoped
范围(可能对某些内容编码过多,应用服务器应该已经支持) - 不要在您的生产者上使用
@ApplicationScoped
,而是将创建的 bean 缓存在 Singleton bean 中(如果它们是之前创建的)