Domanda

I am a guice newbie trying to figure out how to implement assisted inject in the guice using FactoryModuleBuilder. I consulted the guice java docs for implementing FactoryModuleBuilder.

I have done everything exactly as it says in the docs. Its not injecting the factory. I referred to this stack overflow question :Guice AssistedInject won't inject the factory which had the same problem. It talks about the field injection before constructor injection problem. I followed it and I am trying to call the Parent class using a caller class but I am still getting the null pointer exception. What is going wrong here?

Caller class

public class MAIN {

    @Inject private static MyFactory factory;

    public static void main(String[] args){
        ParentClass newbie = new ParentClass(factory);
    }
}

I am still getting the exception:

Exception in thread "main" java.lang.NullPointerException
    at com.pkg.ParentClass.<init>(ParentClass.java:19)
    at com.pkg.MAIN.main(MAIN.java:10)

Parent Class

public class ParentClass {

    private final Foo test;
    @Inject
    public ParentClass(MyFactory factory){
        test = factory.create(new HashMap<String,Object>());
    }
}

Module Implementation: ParentModule

public class ParentModule extends AbstractModule{

    @Override
    protected void configure() {
        install(new FactoryModuleBuilder()
                .implement(Foo.class, FooImpl.class)
                .build(MyFactory.class));
    }

}

Factory Interface: MyFactory

public interface MyFactory {

    Foo create(Map<String,Object> map);
}

Class Interface : Foo

public interface Foo{
}

Class:FooImpl

public class FooImpl implements Foo {

    private final Map<String,Object> mapA;
    @AssistedInject
    public FooImpl(@Assisted Map<String,Object> map){

        mapA=map;
    }

}
È stato utile?

Soluzione

You have two problems here.

First and most important, you are not creating Injector anywhere. Obviously, without an injector nothing will work. You have to create an injector instance using your module:

Injector injector = Guice.createInjector(new ParentModule());

Your second problem is that you want to inject your factory into a static field:

@Inject private static MyFactory factory;

Although Guice can work with static fields if you tell it explicitly, it is considered very bad practice. You should never inject into static fields unless you are working with some legacy code.

What you really want is something like this:

public class Main {
    @Inject
    private MyFactory factory;

    public void run() {
        ParentClass newbie = new ParentClass(factory);
    }

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new ParentModule());
        Main main = injector.getInstance(Main.class);
        main.run();
    }
}

Note that program entry point (main) is now creates an injector and then uses it to create an instance of Main class, which will have its field injected automatically. And then it calls method run() on the instance which performs actual work.

Note, however, that this is all really valid only for illustrative purposes for assisted injection. You should not structure your real code like this. For example, you're using new operator to create classes whose constructors are annotated with @Inject. Don't ever do this! If you mark some class (i.e. its constructors or fields) as @Injectable, then this class should be used only by the means of injection. Your Main code can be shortened to the following:

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new ParentModule());
        ParentClass newbie = injector.getInstance(ParentClass.class);
    }
}

Here newbie will automatically receive an instance of MyFactory into its constructor since it is annotated with @Inject.

And I already wrote about statics.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top