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.

Reply via email to