我正在尝试从CDI 1.0升级到CDI 1.2,但我遇到了以下问题:
org.jboss.weld.exceptions.UnserializableDependencyException: WELD-001413: The bean Managed Bean [class ViewProcessContext] with qualifiers [@Default @Named @Any] declares a passivating scope but has a non-passivation-capable dependency Producer Method [ConfigurationReader] with qualifiers [@Default @Any] declared as [[BackedAnnotatedMethod] @Produces @Default @Singleton public ConfigurationReaderProducer.process()]
at org.jboss.weld.bootstrap.Validator.validateInjectionPointPassivationCapable(Validator.java:442)
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:380)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:277)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:130)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:151)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:494)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:64)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:62)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:62)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:55)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
在CDI 1.0上运行良好的代码如下:
错误发生的地方:
@Named
@ConversationScoped
public class ViewProcessContext implements Externalizable {
//...
@Inject
private ConfigurationReader compReader;
//...
}
注入依赖:
public interface ConfigurationReader extends Serializable {
}
制片:
@ApplicationScoped
public class ConfigurationReaderProducer implements Externalizable {
//...
@Produces
@Default
@Singleton
public ConfigurationReader process() {
}
}
根据CDI spec:
当且仅当从不存在时,生产者方法才具有钝化能力 返回一个在运行时不能钝化的值。
所以我的制作人总是会返回一个具有钝化功能的实例 我无法理解为什么韦尔德抱怨它。
在这种情况下,生产者或依赖关系无效?
答案 0 :(得分:1)
请参阅http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#passivating_scope
第一:生产者方法的验证:
6.6.5。验证具有钝化功能的bean和依赖项
如果生产者方法声明了钝化范围并且:
- 具有声明为final的返回类型,并且不实现或扩展Serializable,或
- 具有不能钝化的注入点。
6.6.1。有能力的豆类
生成器方法是钝化的,当且仅当它永远不会返回在运行时不能钝化的值时。
结论:如果要在具有钝化功能的范围内使用结果,则必须始终使用具有钝化功能的注释对生产者方法进行注释。
嗯,哪些范围是钝化能力?答案:只有会话和会话范围加上你自己声明@NormalScope(passivating = true)的范围。手段,@ Singleton不是(见6.6.4.Passivation范围)。
你可以解决这个问题,但是:
你真的想在talkScope bean中使用Singleton吗?当你的会话史密斯 - Bean将被钝化时,你的单身人士也将会被淘汰。您需要实现readResolve和writeReplace(请参阅Serializable Api)才能真正创建单例。它周围没有代理对象。
重新考虑您的解决方案,在大多数情况下,(代理的)applicationScoped-Object就是您想要的。
尽管如此,你实际上可以通过标准的@Inject机制将@ Singleton-Bean注入@ConversationScope(没有生产者,只需普通注入)。请注意,使用beans.xml和bean-discovery-mode ="注释"会自动检测到@ Singleton-bean。 (你需要readResolve等)。
最后:您是否可以通过生产者方法简单地注入单例而不是有意义吗?我说:不。但那就是它在规范中的写法,我很抱歉。
祝你好运。