WELD-001413:bean ...具有非钝化能力的依赖性Producer Method(CDI 1.2)

时间:2017-03-09 14:26:41

标签: java serialization cdi java-ee-7 weld

我正在尝试从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

  

当且仅当从不存在时,生产者方法才具有钝化能力   返回一个在运行时不能钝化的值。

所以我的制作人总是会返回一个具有钝化功能的实例 我无法理解为什么韦尔德抱怨它。

在这种情况下,生产者或依赖关系无效?

1 个答案:

答案 0 :(得分:1)

嗯,我可以重现你的问题。我重新阅读了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。验证具有钝化功能的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等)。

最后:您是否可以通过生产者方法简单地注入单例而不是有意义吗?我说:不。但那就是它在规范中的写法,我很抱歉。

祝你好运。