WELD-001413:bean ......具有非钝化能力的依赖生产者方法(CDI 1.2)
WELD-001413: The bean... has a non-passivation-capable dependency Producer Method (CDI 1.2)
我正在尝试从 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.doWork(ConcurrentValidator.java:64)
at org.jboss.weld.bootstrap.ConcurrentValidator.doWork(ConcurrentValidator.java:62)
at org.jboss.weld.executor.IterativeWorkerTaskFactory.call(IterativeWorkerTaskFactory.java:62)
at org.jboss.weld.executor.IterativeWorkerTaskFactory.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:
A producer method is passivation capable if and only if it never
returns a value which is not passivation capable at runtime.
所以我的生产者总是 returns 一个能够钝化的实例。
我不明白为什么韦尔德会抱怨它。
在这种情况下,生产者或依赖项有什么无效的?
嗯,我可以重现你的问题。我重新阅读了 CDI 1.0 和 1.2 规范。 CDI 1.2 实际上比 CDI 1.0 更清晰一些,据我所知,Weld 中的更改是非常正确的。
见http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#passivating_scope
首先:生产者方法的验证:
6.6.5.Validation 具有钝化功能的 bean 和依赖项
If a producer method declares a passivating scope and:
- has a return type that is declared final and does not implement or extend Serializable, or,
- has an injection point that is not passivation capable.
6.6.1.Passivation 可用的 bean
A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime.
结论:如果要在支持钝化的范围内使用结果,生产者方法必须始终使用支持钝化的注释进行注释。
那么,哪些示波器可以钝化?回答:只有会话和会话作用域加上您自己声明@NormalScope(passivating=true) 的作用域。意思是,@Singleton 不是(参见 6.6.4.Passivation 范围)。
您也许可以解决该问题,但是:
您真的希望在您的 conversationScope bean 中使用 Singleton 吗?当您的 conversationScoped-Bean 将被钝化时,您的 Singleton 也会被钝化。您需要实现 readResolve 和 writeReplace(参见 Serializable Api)才能真正创建单例。周围不会有代理对象。
重新考虑您的解决方案,在大多数情况下,(代理的)applicationScoped-Object 就是您想要的。
然而,您实际上可以通过标准的@Inject 机制将@Singleton-Bean 注入到@ConversationScope 中(没有生产者,只是普通注入)。请注意,使用 beans.xml 和 bean-discovery-mode="annotated" 不会自动检测到 @Singleton-bean(并且您需要 readResolve 等,如前所述)。
最后:您可以直接注入单例但不能通过生产者方法注入是否有意义?我会说:不。但是规范中是这样写的,对不起。
祝你好运。
在您的 class ConfigurationReaderFacde 外观中添加 @Stateless
@Stateless public class ConfigurationReaderFacde extends AbstractFacade<ConfigurationReaderFacde> { }
我正在尝试从 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.doWork(ConcurrentValidator.java:64)
at org.jboss.weld.bootstrap.ConcurrentValidator.doWork(ConcurrentValidator.java:62)
at org.jboss.weld.executor.IterativeWorkerTaskFactory.call(IterativeWorkerTaskFactory.java:62)
at org.jboss.weld.executor.IterativeWorkerTaskFactory.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:
A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime.
所以我的生产者总是 returns 一个能够钝化的实例。
我不明白为什么韦尔德会抱怨它。
在这种情况下,生产者或依赖项有什么无效的?
嗯,我可以重现你的问题。我重新阅读了 CDI 1.0 和 1.2 规范。 CDI 1.2 实际上比 CDI 1.0 更清晰一些,据我所知,Weld 中的更改是非常正确的。
见http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#passivating_scope
首先:生产者方法的验证:
6.6.5.Validation 具有钝化功能的 bean 和依赖项
If a producer method declares a passivating scope and:
- has a return type that is declared final and does not implement or extend Serializable, or,
- has an injection point that is not passivation capable.
6.6.1.Passivation 可用的 bean
A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime.
结论:如果要在支持钝化的范围内使用结果,生产者方法必须始终使用支持钝化的注释进行注释。
那么,哪些示波器可以钝化?回答:只有会话和会话作用域加上您自己声明@NormalScope(passivating=true) 的作用域。意思是,@Singleton 不是(参见 6.6.4.Passivation 范围)。
您也许可以解决该问题,但是:
您真的希望在您的 conversationScope bean 中使用 Singleton 吗?当您的 conversationScoped-Bean 将被钝化时,您的 Singleton 也会被钝化。您需要实现 readResolve 和 writeReplace(参见 Serializable Api)才能真正创建单例。周围不会有代理对象。
重新考虑您的解决方案,在大多数情况下,(代理的)applicationScoped-Object 就是您想要的。
然而,您实际上可以通过标准的@Inject 机制将@Singleton-Bean 注入到@ConversationScope 中(没有生产者,只是普通注入)。请注意,使用 beans.xml 和 bean-discovery-mode="annotated" 不会自动检测到 @Singleton-bean(并且您需要 readResolve 等,如前所述)。
最后:您可以直接注入单例但不能通过生产者方法注入是否有意义?我会说:不。但是规范中是这样写的,对不起。
祝你好运。
在您的 class ConfigurationReaderFacde 外观中添加 @Stateless
@Stateless public class ConfigurationReaderFacde extends AbstractFacade<ConfigurationReaderFacde> { }