Skip to content

Instantly share code, notes, and snippets.

@saeta
Created October 17, 2015 20:14
Show Gist options
  • Save saeta/1b61fa344beb137de5ff to your computer and use it in GitHub Desktop.
Save saeta/1b61fa344beb137de5ff to your computer and use it in GitHub Desktop.
Governator bootstrap injector binding problem
name := "reproGovernator"
libraryDependencies += "com.netflix.governator" % "governator" % "1.10.5"
libraryDependencies += "com.google.inject" % "guice" % "4.0"
package com.example
import javax.inject.Inject
import com.google.inject.{Injector, Stage, AbstractModule}
import com.netflix.governator.guice.LifecycleInjector
import scala.reflect.ClassTag
case class Foo(a: String = "")
class CommonModule extends AbstractModule {
override def configure(): Unit = {
bind(classOf[Foo]).toInstance(new Foo("asdf"))
}
}
/**
* Similar to Play!'s `play.api.inject.Injector` trait.
*/
trait InjectorWrapper {
// Make available externally.
val guiceInjector: Injector
def instanceOf[T: ClassTag]: T
def instanceOf[T](clazz: Class[T]): T
}
class SimpleInjector @Inject() (override val guiceInjector: Injector) extends InjectorWrapper {
override def instanceOf[T](implicit classTag: ClassTag[T]) =
instanceOf(classTag.runtimeClass.asInstanceOf[Class[T]])
override def instanceOf[T](clazz: Class[T]): T = guiceInjector.getInstance(clazz)
}
class ComplexInjector @Inject() (override val guiceInjector: Injector, val foo: Foo) extends InjectorWrapper {
override def instanceOf[T](implicit classTag: ClassTag[T]) =
instanceOf(classTag.runtimeClass.asInstanceOf[Class[T]])
override def instanceOf[T](clazz: Class[T]): T = guiceInjector.getInstance(clazz)
}
class SimpleModule extends AbstractModule {
override def configure(): Unit = {
bind(classOf[InjectorWrapper]).to(classOf[SimpleInjector])
install(new CommonModule)
}
}
class ComplexModule extends AbstractModule {
override def configure(): Unit = {
bind(classOf[InjectorWrapper]).to(classOf[ComplexInjector])
install(new CommonModule)
}
}
object Hello {
def main(args: Array[String]): Unit = {
val simpleInjectorBld = LifecycleInjector.builder().inStage(Stage.DEVELOPMENT).withModules(new SimpleModule).build()
val simpleInjector = simpleInjectorBld.createInjector()
val simpleInjectorWrapper = simpleInjector.getInstance(classOf[InjectorWrapper])
println("Simple Injector Wrapper underlying:")
println(simpleInjectorWrapper.guiceInjector)
println("\nSimple Injector Wrapper underlying parent:")
println(simpleInjectorWrapper.guiceInjector.getParent)
println("\nSimple Injector parent:")
println(simpleInjector.getParent)
println("\nSimple injector:")
println(simpleInjector)
println("\n\n")
val complexInjectorBld = LifecycleInjector.builder().inStage(Stage.DEVELOPMENT).withModules(new ComplexModule).build()
val complexInjector = complexInjectorBld.createInjector()
val complexInjectorWrapper = complexInjector.getInstance(classOf[InjectorWrapper])
println("Complex Injector Wrapper underlying:")
println(complexInjectorWrapper.guiceInjector)
println("\nComplex Injector Wrapper underlying parent:")
println(complexInjectorWrapper.guiceInjector.getParent)
println("\nComplex Injector parent:")
println(complexInjector.getParent)
println("\nComplex Injector:")
println(complexInjector)
println("\nFoo:")
println(complexInjectorWrapper.asInstanceOf[ComplexInjector].foo)
}
}
@saeta
Copy link
Author

saeta commented Oct 17, 2015

The output from running this is the following:

Simple Injector Wrapper underlying:
Injector{bindings=[InstanceBinding{key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT}, ProviderInstanceBinding{key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>}, ProviderInstanceBinding{key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>}, ProviderInstanceBinding{key=Key[type=java.util.Set<com.netflix.governator.guice.ModuleTransformer>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, provider=Multibinder<com.netflix.governator.guice.ModuleTransformer>}, ProviderInstanceBinding{key=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, provider=com.google.inject.multibindings.Multibinder$RealMultibinder$RealMultibinderCollectionOfProvidersProvider@e7ee8366}, LinkedKeyBinding{key=Key[type=java.util.Collection<javax.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, target=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]]}, ProviderInstanceBinding{key=Key[type=java.util.Set<com.netflix.governator.guice.PostInjectorAction>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, provider=Multibinder<com.netflix.governator.guice.PostInjectorAction>}, ProviderInstanceBinding{key=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, provider=com.google.inject.multibindings.Multibinder$RealMultibinder$RealMultibinderCollectionOfProvidersProvider@c95e0c1b}, LinkedKeyBinding{key=Key[type=java.util.Collection<javax.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, target=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]]}, ProviderKeyBinding{key=Key[type=com.netflix.governator.lifecycle.LifecycleConfigurationProviders, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:98), scope=eager singleton, provider=Key[type=com.netflix.governator.guice.InternalBootstrapModule$LifecycleConfigurationProvidersProvider, annotation=[none]]}, ProviderInstanceBinding{key=Key[type=com.netflix.governator.lifecycle.ClasspathScanner, annotation=[none]], source=public com.netflix.governator.lifecycle.ClasspathScanner com.netflix.governator.guice.InternalBootstrapModule.getClasspathScanner(), scope=Scopes.SINGLETON, provider=@Provides com.netflix.governator.guice.InternalBootstrapModule.getClasspathScanner(InternalBootstrapModule.java:124)}, ConstructorBinding{key=Key[type=com.netflix.governator.configuration.ConfigurationDocumentation, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:83), scope=Scopes.SINGLETON}, ConstructorBinding{key=Key[type=com.netflix.governator.lifecycle.LifecycleManager, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:97), scope=eager singleton}]}

Simple Injector Wrapper underlying parent:
null

Simple Injector parent:
Injector{bindings=[InstanceBinding{key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT}, ProviderInstanceBinding{key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>}, ProviderInstanceBinding{key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>}, ProviderInstanceBinding{key=Key[type=java.util.Set<com.netflix.governator.guice.ModuleTransformer>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, provider=Multibinder<com.netflix.governator.guice.ModuleTransformer>}, ProviderInstanceBinding{key=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, provider=com.google.inject.multibindings.Multibinder$RealMultibinder$RealMultibinderCollectionOfProvidersProvider@e7ee8366}, LinkedKeyBinding{key=Key[type=java.util.Collection<javax.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, target=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]]}, ProviderInstanceBinding{key=Key[type=java.util.Set<com.netflix.governator.guice.PostInjectorAction>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, provider=Multibinder<com.netflix.governator.guice.PostInjectorAction>}, ProviderInstanceBinding{key=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, provider=com.google.inject.multibindings.Multibinder$RealMultibinder$RealMultibinderCollectionOfProvidersProvider@c95e0c1b}, LinkedKeyBinding{key=Key[type=java.util.Collection<javax.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, target=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]]}, ProviderKeyBinding{key=Key[type=com.netflix.governator.lifecycle.LifecycleConfigurationProviders, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:98), scope=eager singleton, provider=Key[type=com.netflix.governator.guice.InternalBootstrapModule$LifecycleConfigurationProvidersProvider, annotation=[none]]}, ProviderInstanceBinding{key=Key[type=com.netflix.governator.lifecycle.ClasspathScanner, annotation=[none]], source=public com.netflix.governator.lifecycle.ClasspathScanner com.netflix.governator.guice.InternalBootstrapModule.getClasspathScanner(), scope=Scopes.SINGLETON, provider=@Provides com.netflix.governator.guice.InternalBootstrapModule.getClasspathScanner(InternalBootstrapModule.java:124)}, ConstructorBinding{key=Key[type=com.netflix.governator.configuration.ConfigurationDocumentation, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:83), scope=Scopes.SINGLETON}, ConstructorBinding{key=Key[type=com.netflix.governator.lifecycle.LifecycleManager, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:97), scope=eager singleton}]}

Simple injector:
Injector{bindings=[InstanceBinding{key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT}, ProviderInstanceBinding{key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>}, ProviderInstanceBinding{key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>}, LinkedKeyBinding{key=Key[type=com.example.InjectorWrapper, annotation=[none]], source=com.example.SimpleModule.configure(Hello.scala:46), scope=Scopes.NO_SCOPE, target=Key[type=com.example.SimpleInjector, annotation=[none]]}, InstanceBinding{key=Key[type=com.example.Foo, annotation=[none]], source=com.example.CommonModule.configure(Hello.scala:14), instance=Foo(asdf)}]}



Complex Injector Wrapper underlying:
Injector{bindings=[InstanceBinding{key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT}, ProviderInstanceBinding{key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>}, ProviderInstanceBinding{key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>}, LinkedKeyBinding{key=Key[type=com.example.InjectorWrapper, annotation=[none]], source=com.example.ComplexModule.configure(Hello.scala:53), scope=Scopes.NO_SCOPE, target=Key[type=com.example.ComplexInjector, annotation=[none]]}, InstanceBinding{key=Key[type=com.example.Foo, annotation=[none]], source=com.example.CommonModule.configure(Hello.scala:14), instance=Foo(asdf)}]}

Complex Injector Wrapper underlying parent:
Injector{bindings=[InstanceBinding{key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT}, ProviderInstanceBinding{key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>}, ProviderInstanceBinding{key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>}, ProviderInstanceBinding{key=Key[type=java.util.Set<com.netflix.governator.guice.ModuleTransformer>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, provider=Multibinder<com.netflix.governator.guice.ModuleTransformer>}, ProviderInstanceBinding{key=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, provider=com.google.inject.multibindings.Multibinder$RealMultibinder$RealMultibinderCollectionOfProvidersProvider@e7ee8366}, LinkedKeyBinding{key=Key[type=java.util.Collection<javax.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, target=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]]}, ProviderInstanceBinding{key=Key[type=java.util.Set<com.netflix.governator.guice.PostInjectorAction>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, provider=Multibinder<com.netflix.governator.guice.PostInjectorAction>}, ProviderInstanceBinding{key=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, provider=com.google.inject.multibindings.Multibinder$RealMultibinder$RealMultibinderCollectionOfProvidersProvider@c95e0c1b}, LinkedKeyBinding{key=Key[type=java.util.Collection<javax.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, target=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]]}, ProviderKeyBinding{key=Key[type=com.netflix.governator.lifecycle.LifecycleConfigurationProviders, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:98), scope=eager singleton, provider=Key[type=com.netflix.governator.guice.InternalBootstrapModule$LifecycleConfigurationProvidersProvider, annotation=[none]]}, ProviderInstanceBinding{key=Key[type=com.netflix.governator.lifecycle.ClasspathScanner, annotation=[none]], source=public com.netflix.governator.lifecycle.ClasspathScanner com.netflix.governator.guice.InternalBootstrapModule.getClasspathScanner(), scope=Scopes.SINGLETON, provider=@Provides com.netflix.governator.guice.InternalBootstrapModule.getClasspathScanner(InternalBootstrapModule.java:124)}, ConstructorBinding{key=Key[type=com.netflix.governator.configuration.ConfigurationDocumentation, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:83), scope=Scopes.SINGLETON}, ConstructorBinding{key=Key[type=com.netflix.governator.lifecycle.LifecycleManager, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:97), scope=eager singleton}]}

Complex Injector parent:
Injector{bindings=[InstanceBinding{key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT}, ProviderInstanceBinding{key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>}, ProviderInstanceBinding{key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>}, ProviderInstanceBinding{key=Key[type=java.util.Set<com.netflix.governator.guice.ModuleTransformer>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, provider=Multibinder<com.netflix.governator.guice.ModuleTransformer>}, ProviderInstanceBinding{key=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, provider=com.google.inject.multibindings.Multibinder$RealMultibinder$RealMultibinderCollectionOfProvidersProvider@e7ee8366}, LinkedKeyBinding{key=Key[type=java.util.Collection<javax.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:69), scope=Scopes.NO_SCOPE, target=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.ModuleTransformer>>, annotation=[none]]}, ProviderInstanceBinding{key=Key[type=java.util.Set<com.netflix.governator.guice.PostInjectorAction>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, provider=Multibinder<com.netflix.governator.guice.PostInjectorAction>}, ProviderInstanceBinding{key=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, provider=com.google.inject.multibindings.Multibinder$RealMultibinder$RealMultibinderCollectionOfProvidersProvider@c95e0c1b}, LinkedKeyBinding{key=Key[type=java.util.Collection<javax.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]], source=com.netflix.governator.guice.BootstrapBinder.<init>(BootstrapBinder.java:70), scope=Scopes.NO_SCOPE, target=Key[type=java.util.Collection<com.google.inject.Provider<com.netflix.governator.guice.PostInjectorAction>>, annotation=[none]]}, ProviderKeyBinding{key=Key[type=com.netflix.governator.lifecycle.LifecycleConfigurationProviders, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:98), scope=eager singleton, provider=Key[type=com.netflix.governator.guice.InternalBootstrapModule$LifecycleConfigurationProvidersProvider, annotation=[none]]}, ProviderInstanceBinding{key=Key[type=com.netflix.governator.lifecycle.ClasspathScanner, annotation=[none]], source=public com.netflix.governator.lifecycle.ClasspathScanner com.netflix.governator.guice.InternalBootstrapModule.getClasspathScanner(), scope=Scopes.SINGLETON, provider=@Provides com.netflix.governator.guice.InternalBootstrapModule.getClasspathScanner(InternalBootstrapModule.java:124)}, ConstructorBinding{key=Key[type=com.netflix.governator.configuration.ConfigurationDocumentation, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:83), scope=Scopes.SINGLETON}, ConstructorBinding{key=Key[type=com.netflix.governator.lifecycle.LifecycleManager, annotation=[none]], source=com.netflix.governator.guice.InternalBootstrapModule.configure(InternalBootstrapModule.java:97), scope=eager singleton}]}

Complex Injector:
Injector{bindings=[InstanceBinding{key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT}, ProviderInstanceBinding{key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>}, ProviderInstanceBinding{key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>}, LinkedKeyBinding{key=Key[type=com.example.InjectorWrapper, annotation=[none]], source=com.example.ComplexModule.configure(Hello.scala:53), scope=Scopes.NO_SCOPE, target=Key[type=com.example.ComplexInjector, annotation=[none]]}, InstanceBinding{key=Key[type=com.example.Foo, annotation=[none]], source=com.example.CommonModule.configure(Hello.scala:14), instance=Foo(asdf)}]}

Foo:
Foo(asdf)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment