Guice堆栈跟踪未完成

时间:2015-12-02 01:09:18

标签: guice

我记得guice堆栈跟踪曾经从我使用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所有

1 个答案:

答案 0 :(得分:2)

堆栈跟踪未完全完成,因为Guice实际上并未调用相关方法。

在注射器创建时,Guice仍然会验证它可以发现自己的整个图形。开发模式将affect singleton creation但不是注入器验证:不允许您引用Guice永远无法提供的内容,否则Guice会面临更难以调试的运行时异常。

看起来Guice可以检测到对ClientId的需求,而ClientId没有(也可能不应该)有@Inject - 带注释的构造函数。即使它没有被调用,你需要提供它,以便Guice可以声明其图形完整。这就是为什么添加@Provides方法有助于解决问题,即使它从未被调用过 - 你可以同样拥有它throw new RuntimeException()

虽然堆栈跟踪实际上并不反映真正的调用,但它应该足够完整,以便您识别Guice无法提供的依赖关系。我只能想象您编辑的ClientXXX通过@Inject - 带注释的构造函数中的参数或@Inject - 带注释的字段或buildRemoteClient()的参数(然后是2015-12-27T00:00:00.000Z来请求ClientId被视为依赖)。你知道@Inject构造函数或@Provides方法将ClientId作为参数的任何地方吗?

(我不知道Modules.override是否应该让你不必提供完整的原始图表,也不知道Guice 4.0中是否有任何改变的行为。也许是另一个回答者。)