Using geese injections with a pointer-pointer

I get a null pointer exception in the field input of a server that starts as an acc actor.

The grafical part:

private ActorRef myActor = Akka.system().actorOf( new Props(Retreiver.class)); @Override public void onStart(Application app) { log.info("Starting schedular.....!"); Akka.system() .scheduler() .schedule(Duration.create(0, TimeUnit.MILLISECONDS), Duration.create(30, TimeUnit.MINUTES), myActor, "tick", Akka.system().dispatcher()); } 

Part of the Retreiver class:

 public class Retreiver extends UntypedActor { private Logger.ALogger log = Logger.of(Retreiver .class); @Inject private myDataService dataService; @Override public void onReceive(Object arg0) throws Exception { if (0 != dataService.getDataCount()) { .... .... .... } 

}

I get null for dataService. Please advise me about this.

Thanks.

+6
source share
3 answers

You get a NullPointerException because Akka creates your Retriever actor, not Guice. You need Guice to build your instance and then pass this to Akka, IndirectActorProducer can help you with this, for example:

 class RetrieverDependencyInjector implements IndirectActorProducer { final Injector injector; public RetrieverDependencyInjector(Injector injector) { this.injector = injector; } @Override public Class<? extends Actor> actorClass() { return Retriever.class; } @Override public Retriever produce() { return injector.getInstance(Retriever.class); } } 

Note that produce() must create a new instance of Actor every time it is called, it cannot return the same instance.

You can then get Akka to retrieve your actor through RetrieverDependencyInjector , for example:

 ActorRef myActor = Akka.system().actorOf( Props.create(RetrieverDependencyInjector.class, injector) ); 

UPDATE

I was thinking about what you will comment further, you can turn RetrieverDependencyInjector into a GenericDependencyInjector by providing the Actor class that you want as a constructor parameter, which will probably allow you to do something like:

 Props.create(GenericDependencyInjector.class, injector, Retriever.class) 

I have not tried this, but it can give you a starting point.

+7
source

For those who need it:

 public class GuiceInjectedActor implements IndirectActorProducer { final Injector injector; final Class<? extends Actor> actorClass; public GuiceInjectedActor(Injector injector, Class<? extends Actor> actorClass) { this.injector = injector; this.actorClass = actorClass; } @Override public Class<? extends Actor> actorClass() { return actorClass; } @Override public Actor produce() { return injector.getInstance(actorClass); } 

}

AND

 Akka.system().actorOf(Props.create(GuiceInjectedActor.class, INJECTOR,Retreiver.class)) 

Thats it ... !!!

+8
source

There may be other ways, for example, you can put a static injector descriptor in Boot or Some-Injector-Holder-class and insert when creating an actor by calling the inherited method: preStart ()

 public class Retreiver extends UntypedActor { private Logger.ALogger log = Logger.of(Retreiver .class); @Override public void preStart () { super.preStart (); Boot.injector.injectMembers (this); //Some-Injector-holder.injectMembers (this); } @Inject private myDataService dataService; @Override public void onReceive(Object arg0) throws Exception { if (0 != dataService.getDataCount()) { .... .... .... } } 

and also you can enter the injector into the actor provider to initialize the actor with the injector in the UntypedActorFactory area:

 public class InjectingActorProvider implements Provider<ActorRef> { @Inject private Injector injector; @SuppressWarnings("serial") @Override public final ActorRef get() { Props props = new Props(new UntypedActorFactory() { @Override public Actor create() { return injector.getInstance(actorClass); } }); props = props.withRouter(...); props = props.withDispatcher(...); actor = system.actorOf(props, actorName); return actor; } } 
+2
source

Source: https://habr.com/ru/post/949304/


All Articles