2015-12-02 39 views
0

我記得以前是完整的,從開始我inject.getInstance(App.class)獲取對象吉斯堆棧跟蹤信息是不完全的

出於某種原因,一路吉斯堆棧跟蹤,堆棧跟蹤現在停止在像這樣的提供方法

@Provides 
public Interface buildRemoteClient() { } 

,所以我有

at ClientXXX 
at XXXModule.buildRemoteClient() 

則做了什麼?這是非常奇怪的,因爲我在我的TestModule中覆蓋了這個方法。我沒有看到誰被注入,因爲在此方法被調用之前應該已經切斷鏈。有沒有更改guice 4.0或其他?

更多細節

at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466) 
        at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155) 
        at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107) 
        at com.google.inject.Guice.createInjector(Guice.java:96) 
        at com.google.inject.Guice.createInjector(Guice.java:73) 
        at com.google.inject.Guice.createInjector(Guice.java:62) 
        at com.company.search.generalserver.GeneralServer.initialize(GeneralServer.java:166) 

,最後這個(是的,這是我覺得很奇怪,整個事情)...

2) Could not find a suitable constructor in com.company.finagle.thrift.ClientId. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private. 
        at com.company.finagle.thrift.ClientId.class(ClientId.scala:7) 
        at com.company.search.hydrator.app.XXXXModule.buildRemoteClient(XXXXModule.java:37) (via modules: com.google.inject.util.Modules$OverrideModule -> com.google.inject.util.Modules$CombinedModule -> com.twitter.search.hydrator.app.XXXXModule) 

好了,所以我加了這個代碼,它令人驚訝的現在的作品,但從來沒有停止在這個代碼的中斷點。它從來沒有執行在所有這些代碼....

@Provides 
@Singleton 
private ClientId provideId() { 
    return new ClientId("hydrator"); 
} 

因爲我重寫並應切割鏈我應該不需要代碼...這是非常奇怪的,但我想它會檢查每個依賴甚至儘管我處於測試模式,並且ClientId根本不需要。

+0

你能提供示例堆棧跟蹤? –

+0

@MattBall我增加了更多的細節,但基本上是整個堆棧跟蹤(只有兩行)。我不明白爲什麼它沒有在那個堆棧跟蹤中使用App.class,因爲它是最重要的構造函數,它使得所有東西都被構造出來......這太奇怪了。 –

+0

你現在是否正在使用'Stage.PRODUCTION'? –

回答

2

堆棧跟蹤不完全完整,因爲Guice實際上沒有調用相關方法。

在注射器創建時,Guice仍然會驗證它可以發現自己的整個圖形。開發模式將爲affect singleton creation,但不是噴射器驗證:您不能參考Guice永遠不能提供的內容,否則Guice冒着更難以調試的運行時異常。

它看起來像Guice可以檢測到一個ClientId的需要,它沒有(也可能不應該)有一個@Inject-annotated構造函數。即使它沒有被調用,你也需要提供它,所以Guice可以聲明它的圖形完整。這就是爲什麼加入你的@Provides方法可以幫助你解決問題的方法,即使它從未被調用 - 你也可以使用throw new RuntimeException()

雖然堆棧跟蹤並不真實反映真實的調用,但它應該足夠完整,可以確定Guice無法提供的依賴關係。我只能想象你的編輯ClientXXX通過@Inject -annated構造函數中的參數或@Inject -annotated字段或buildRemoteClient()(它隨後被視爲依賴項)的參數通過參數請求ClientId。你知道@Inject構造函數或@Provides方法將ClientId作爲參數嗎?

(我不知道是否Modules.override應該不必提供完整的原始圖饒了你,也沒有在吉斯4.0是否任何行爲的改變,也許另一個回答者會。)