2017-03-09 21 views
0

我試圖從升級CDI 1.0 CDI到1.2,但我現在面臨以下問題:WELD-001413:將綠豆...具有非鈍化能力的依賴生產者方法(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

生產者方法是鈍化能夠當且僅當它從未 返回一個值,該值不鈍化在運行時有效。

所以我的製作人總是返回一個鈍化能力的實例。
我不明白爲什麼Weld會抱怨。

這種情況下生產者或依賴關係是無效的?

+0

你檢查過你是否使用了正確的Singleton-Annotation嗎? –

+0

我剛剛檢查了@markus_,它是正確的('javax.inject.Singleton') –

+0

奇怪的部分是它曾經在CDI 1.0上工作。我更新到CDI 1.2和Weld 2.3.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.Validation能夠豆類和依賴性

如果生成方法聲明瞭一個鈍化範圍和:

  • 有一個返回類型,聲明爲final,並且不實現或擴展S或者,具有不具有鈍化能力的注入點,或者
  • 具有不具有鈍化能力的注入點。

6.6.1.Passivation能夠豆

生產者方法能夠鈍化當且僅當它永遠不會返回其在運行時不會鈍化能的值。

結論:生產者方法必須以一個鈍化能夠標註,如果你想使用導致鈍化能力範圍進行註釋。

那麼,哪些範圍是鈍化能力?答案:只有會話和會話範圍加上你自己的聲明@NormalScope(passivating = true)的範圍。意思是,@Singleton不是(見6.6.4。激活範圍)。

你或許可以解決這個問題,但是:

你真正想要的辛格爾頓在你的conversationScope豆使用?當你談話時,大豆將被鈍化,你的單身人士也會如此。您需要實現readResolve和writeReplace(請參閱Serializable Api)才能真正創建單例。周圍不會有代理對象。

反思您的解決方案,在大多數情況下,(代理)applicationScoped-Object是您想要的。不過,你實際上可以通過標準的@Inject機制(沒有生產者,只是普通注入)將@ Singleton-Bean注入@ConversationScope。請注意,不會使用beans.xml和bean-discovery-mode =「annotated」自動檢測@ Singleton-bean(並且您需要readResolve等,如上所述)。

最後:有意義的是,你可以簡單地注入一個單例,但不能通過生產者方法?我會說:不。但是這就是它在規範中的寫法,我很抱歉。

祝你好運。

+0

很好的解釋@markus_!這一點的確是製片人的範圍。我已經更改爲ApplicationScoped。儘管我不明白爲什麼Singleton和AplicationScoped以不同的方式工作...... –

+0

我仍然懷疑Weld是否應該在這種情況下驗證我的字段,因爲我使用Externalizable接口進行精細/手動序列化,而不是反思一(Serializable)。所以,對我來說,使用Externalizable時不應該檢查我的字段 –