Guice 堆栈跟踪不完整
Guice stack trace was not complete
我记得 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全部.
堆栈跟踪未完全完成,因为 Guice 实际上并未调用有问题的方法。
在创建注入器时,Guice 仍会验证它可以自行发现的整个图表。开发模式将 affect singleton creation 但不是注入器验证:您不允许引用 Guice 永远无法提供的东西,否则 Guice 会面临更难调试的运行时异常。
看起来 Guice 可以检测到对 ClientId 的需求,它没有(并且可能不应该)具有 @Inject
-注释的构造函数。即使它没有被调用,您也需要提供它以便 Guice 可以声明它的图是完整的。这就是为什么添加您的 @Provides
方法会有所帮助,即使它从未被调用——您同样可以拥有它 throw new RuntimeException()
.
尽管堆栈跟踪实际上并未反映真正的调用,但它应该足够完整,您可以识别 Guice 无法提供的依赖项。我只能想象您编辑的 ClientXXX 通过 @Inject
-注释构造函数中的参数或作为 @Inject
-注释字段,或作为 buildRemoteClient()
的参数(然后视为依赖)。您是否知道 @Inject 构造函数或 @Provides 方法将 ClientId 作为参数的任何地方?
(我不知道 Modules.override 是否应该让您不必提供完整的原始图表,也不知道 Guice 4.0 中是否有任何行为发生了变化。也许另一个回答者会。)
我记得 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全部.
堆栈跟踪未完全完成,因为 Guice 实际上并未调用有问题的方法。
在创建注入器时,Guice 仍会验证它可以自行发现的整个图表。开发模式将 affect singleton creation 但不是注入器验证:您不允许引用 Guice 永远无法提供的东西,否则 Guice 会面临更难调试的运行时异常。
看起来 Guice 可以检测到对 ClientId 的需求,它没有(并且可能不应该)具有 @Inject
-注释的构造函数。即使它没有被调用,您也需要提供它以便 Guice 可以声明它的图是完整的。这就是为什么添加您的 @Provides
方法会有所帮助,即使它从未被调用——您同样可以拥有它 throw new RuntimeException()
.
尽管堆栈跟踪实际上并未反映真正的调用,但它应该足够完整,您可以识别 Guice 无法提供的依赖项。我只能想象您编辑的 ClientXXX 通过 @Inject
-注释构造函数中的参数或作为 @Inject
-注释字段,或作为 buildRemoteClient()
的参数(然后视为依赖)。您是否知道 @Inject 构造函数或 @Provides 方法将 ClientId 作为参数的任何地方?
(我不知道 Modules.override 是否应该让您不必提供完整的原始图表,也不知道 Guice 4.0 中是否有任何行为发生了变化。也许另一个回答者会。)