Hi,
There is something I don't understand about binding a listener. Apparently
the mere presence of the bind fires for every class that is bound in a
module. This is causing me issues, as it means trying to request an
injection for a matcher for example will fail.
Here is code you can hopefully literally copy and paste into a class called
"MyModule". Please excuse the blatant misuse of the module class, I'm
merely sticking everything into one class for demonstration purposes.
import java.util.logging.Logger;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
public class MyModule extends AbstractModule
{
@Override
protected void configure()
{
bind(ConcreteClass.class);
MyMatcher matcher = new MyMatcher();
requestInjection(matcher);
bindListener(matcher, new MyTypeListener());
}
private static class ConcreteClass
{
@Inject
public ConcreteClass(Logger log)
{
log.info("ConcreteClass: I got injected!");
}
}
private static class MyMatcher extends AbstractMatcher<TypeLiteral<?>>
{
@Inject
private Logger log;
public boolean matches(TypeLiteral<?> type)
{
System.out.println("I've been called to try and match '" +
type.toString() + "'.");
if (type.getRawType().equals(ConcreteClass.class))
{
log.info("MyMatcher: I found a concrete class!");
}
return true;
}
}
private static class MyTypeListener implements TypeListener
{
@Override
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I>
encounter)
{
// No need for code here to simplify example.
}
}
/**
* @param args
*/
public static void main(String[] args)
{
Injector injector = Guice.createInjector(new MyModule());
injector.getInstance(ConcreteClass.class);
}
}
If I run the code as-is, I get:
I've been called to try and match 'MyModule$ConcreteClass'. <-- Why was
the matcher fired for ConcreteClass? No instances were requested yet
Exception in thread "main"
com.google.inject.internal.util.$ComputationException:
com.google.inject.internal.util.$ComputationException:
java.lang.NullPointerException
at
com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:553)
at
com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:419)
at
com.google.inject.internal.util.$CustomConcurrentHashMap$ComputingImpl.get(CustomConcurrentHashMap.java:2041)
at com.google.inject.internal.FailableCache.get(FailableCache.java:50)
at
com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:49)
at
com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:125)
at
com.google.inject.internal.InjectorImpl.initializeBinding(InjectorImpl.java:507)
at
com.google.inject.internal.AbstractBindingProcessor$Processor$1.run(AbstractBindingProcessor.java:159)
at
com.google.inject.internal.ProcessedBindingData.initializeBindings(ProcessedBindingData.java:44)
at
com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:122)
at
com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
at com.google.inject.Guice.createInjector(Guice.java:95)
at com.google.inject.Guice.createInjector(Guice.java:72)
at com.google.inject.Guice.createInjector(Guice.java:62)
at MyModule.main(MyModule.java:85)
Caused by: com.google.inject.internal.util.$ComputationException:
java.lang.NullPointerException
at
com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:553)
at
com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:419)
at
com.google.inject.internal.util.$CustomConcurrentHashMap$ComputingImpl.get(CustomConcurrentHashMap.java:2041)
at com.google.inject.internal.FailableCache.get(FailableCache.java:50)
at
com.google.inject.internal.MembersInjectorStore.get(MembersInjectorStore.java:65)
at
com.google.inject.internal.ConstructorInjectorStore.createConstructor(ConstructorInjectorStore.java:73)
at
com.google.inject.internal.ConstructorInjectorStore.access$000(ConstructorInjectorStore.java:28)
at
com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:36)
at
com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:32)
at
com.google.inject.internal.FailableCache$1.apply(FailableCache.java:39)
at
com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:549)
... 14 more
Caused by: java.lang.NullPointerException
at MyModule$MyMatcher.matches(MyModule.java:64) <--- This is the
log.info() line in the matcher failing because log is null
at MyModule$MyMatcher.matches(MyModule.java:1)
at
com.google.inject.internal.MembersInjectorStore.createWithListeners(MembersInjectorStore.java:100)
at
com.google.inject.internal.MembersInjectorStore.access$000(MembersInjectorStore.java:34)
at
com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:42)
at
com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:39)
at
com.google.inject.internal.FailableCache$1.apply(FailableCache.java:39)
at
com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:549)
... 24 more
If I comment out the bindListener everything works (of course the matcher
is not used):
Aug 28, 2012 10:47:48 PM MyModule$ConcreteClass <init>
INFO: ConcreteClass: I got injected!
So I guess my question is, am I doing something wrong? If the listener is
supposed to fire for each class that is bound, how do I go about requesting
injection of a matcher? Also, in my real life example, even if I comment
out the log line in the matcher, my listener ends up failing because I'm
trying to ask the encounter in the registered InjectionListener to provide
me with the logger. It ends up telling me injector was not created yet.
Thanks for any help you can provide.
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/google-guice/-/b4VtmShntCAJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en.