Table of contents
1.
Introduction
2.
Integrating with Akka
3.
The Application Actor System
3.1.
Writing Actors
3.2.
Creating and Using Actors
4.
Dependency Injecting Actors
4.1.
Dependency Injecting Child Actors
5.
Configuration
5.1.
Changing configuration prefix
5.2.
Built-in actor system name
6.
Frequently Asked Questions
6.1.
What is Akka?
6.2.
What is an Actor in Akka?
6.3.
What is Akka ActorSystem?
6.4.
What are the components of the Akka ActorSystem?
6.5.
How is Akka ActorSystem Configuration Used?
7.
Conclusion
Last Updated: Mar 27, 2024
Easy

Java Developers-Integration with Akka

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Akka is a free and open-source library and toolset. It is employed in the development of concurrent, distributed, and fault-tolerant applications. This library is compatible with any JVM (Java Virtual Machine) supported language. This will be integrated into the Scala programming language in this course. Scala is used to writing Akka. It employs the Actor Based Model. For creating concurrent and distributed applications, the Actor Model provides a greater degree of abstraction. It assists programmers in dealing with explicit locking and thread management. Akka simplifies the development of proper concurrent and parallel applications. 

Integrating with Akka

Integrating with Akka

Akka employs the Actor Model to increase abstraction and give a better foundation for developing proper concurrent and scalable systems. It uses the 'Let it crash' concept for fault tolerance, which has been used successfully in the telecoms industry to construct self-healing applications - systems that never stop. Actors also serve as the abstraction for transparent distribution and serve as the foundation for highly scalable and fault-tolerant systems.

The Application Actor System

The Application Actor System

Akka may interact with a variety of containers known as actor systems. An actor system handles the resources that it is set up to utilize in order to execute the actors contained inside it.

A Play application describes a custom actor system that the application will utilize. This actor system tracks the lifecycle of the application and restarts automatically when the program resumes.

Writing Actors

To begin utilizing Akka, you must first create an actor. The Actor below just says hi to anyone who requests it.

package actors;
Import Akka. Actor.*;
import Akka.japi.*;
import actors.HiactorProtocol.*;


public class Hiactor extends AbstractActor {


  public static Props getProps() {
    return Props.create(Hiactor.class);
  }


  @Override
  public Receive createReceive() {
    return receiveBuilder()
        .match(
            SayHelloThere.class,
            hello -> {
              String reply = "Hello, " + hello.name;
              sender().tell(reply, self());
            })
        .build();
  }
}
You can also try this code with Online Java Compiler
Run Code

 

The Hiactor offers a static function called getProps, which returns a Props object that details how to build the Actor. To segregate the instantiation logic from the code that generates the Actor is a useful Akka convention.

Another recommended practice demonstrated here is that the messages sent and received by Hiactor are declared as static inner classes of another class named HiactorProtocol:

package actors;
public class HiactorProtocol {


  public static class SayHelloThere {
    public final String name;


    public SayHelloThere(String name) {
      this.name = name;
    }
  }
}
You can also try this code with Online Java Compiler
Run Code

 

Creating and Using actors

Creating and Using Actors

An ActorSystem is required to generate and/or use an actor. You can get this by declaring a reliance on an ActorSystem and then using the actorOf method to create a new actor.

Sending a message to an actor is the most fundamental thing you can do. There is no reaction when you send a message to an actor; it's fire and forgets. This is often referred to as the tell pattern.

However, because HTTP is a protocol with requests and answers, the tell pattern is frequently ineffective in a web application. In this scenario, the ask pattern is considerably more likely to be appropriate. The ask pattern yields a Scala Future, which you can then map to your own result type by converting it to a Java CompletionStage using scala.compat.java8.FutureConverts.toJava.

Here's an example of how to use our Hiactor with the ask pattern:

import akka. Actor.*;
import play.mvc.*;
import scala.compat.java8.FutureConverters;
import javax.inject.*;
import java.util.concurrent.CompletionStage;


import static akka.pattern.Patterns.ask;


@Singleton
public class Application extends controller {


  final ActorRef Hiactor;


  @Inject
  public Application(ActorSystem system) {
    Hiactor = system.actorOf(Hiactor.getProps());
  }


  public CompletionStage<Result> SayHelloThere(String name) {
    return FutureConverters.toJava(ask(Hiactor, new SayHelloThere(name), 1000))
        .thenApply(response -> ok((String) response));
  }
}
You can also try this code with Online Java Compiler
Run Code

 

A few points to consider:

  • The ask pattern must be imported; it is typically easiest to static import the ask function.
     
  • A CompletionStage is created from the returning future. Because the resultant promise is a <CompletionStageObject>, you must cast its value to the type you anticipate from the Actor when you access its value.
     
  • The ask pattern necessitates a timeout, which we have set to 1000 milliseconds. If the Actor takes more than that amount of time to react, the returned promise will be fulfilled with a timeout error.
     
  • We need to scope our controller as Singleton because we're constructing the Actor in the constructor so that a new actor isn't produced every time this controller is used.

Actor System

Dependency Injecting Actors

If you choose, Guice can instantiate your actors and assign actor refs to them on which your controllers and components will rely.

For example, if you needed an actor that was dependent on the Play setting, you might perform the following:

import Akka. Actor.AbstractActor;
import com.typesafe.config.Config;

Import javax.inject.Inject;

public class ConfiguredActor extends AbstractActor {

  private Config configuration;


  @Inject
  public ConfiguredActor(Config configuration) {
    this.configuration = configuration;
  }

  @Override
  public Receive createReceive() {
    return receiveBuilder()
        .match(
            ConfiguredActorProtocol.GetConfig.class,
            message -> {
              sender().tell(configuration.getString("my.config"), self());
            })
        .build();
  }
}
You can also try this code with Online Java Compiler
Run Code

 

Play includes some aids to aid in the provision of actor bindings. These allow the Actor to be dependency injected as well as the actor ref to be injected into other components. Create a module as indicated in the dependency injection documentation, then mix in the AkkaGuiceSupport interface and bind the Actor using the bindActor method:

import com.google.inject.AbstractModule;
import play.libs.akka.AkkaGuiceSupport;


public class MyModule extends AbstractModule implements AkkaGuiceSupport {
  @Override
  protected void configure() {
    bindActor(ConfiguredActor.class, "configured-actor");
  }
}
You can also try this code with Online Java Compiler
Run Code

 

For injection, this Actor will be called configured-actor and qualified with the configured-actor name. In your controllers and other components, you may now rely on the Actor:

import Akka. Actor.ActorRef;
import play.mvc.*;
import scala.compat.java8.FutureConverters;


Import javax.inject.Inject;
import javax.inject.Named;
import java.util.concurrent.CompletionStage;


import static akka.pattern.Patterns.ask;


public class Application extends controller {


  private ActorRef configuredActor;


  @Inject
  public Application(@Named("configured-actor") ActorRef configuredActor) {
    this.configuredActor = configuredActor;
  }


  public CompletionStage<Result> getConfig() {
    return FutureConverters.toJava(
            ask(configuredActor, new ConfiguredActorProtocol.GetConfig(), 1000))
        .thenApply(response -> ok((String) response));
  }
}
You can also try this code with Online Java Compiler
Run Code

 

Dependency Injecting Child Actors

Dependency Injecting Child Actors

The preceding is useful for injecting root actors, but many of the actors you generate will be child actors that are not connected to the Play app's lifecycle and may get an extra state.

Guice's AssistedInject assistance is used by Play to aid with dependency injecting kid actors.

Assume you have the following Actor, which is dependent on the configuration to be injected, as well as a key:

import Akka. Actor.AbstractActor;
import com.google.inject.assistedinject.Assisted;
import com.typesafe.config.Config;


Import javax.inject.Inject;


public class ConfiguredChildActor extends AbstractActor {


  private final Config configuration;
  private final String key;


  @Inject
  public ConfiguredChildActor(Config configuration, @Assisted String key) {
    this.configuration = configuration;
    this.key = key;
  }


  @Override
  public Receive createReceive() {
    return receiveBuilder()
        .match(ConfiguredChildActorProtocol.GetConfig.class, this::getConfig)
        .build();
  }


  private void getConfig(ConfiguredChildActorProtocol.GetConfig get) {
    sender().tell(configuration.getString(key), self());
  }
}
You can also try this code with Online Java Compiler
Run Code

 

We utilized function Object() { [native code] } injection in this scenario since Guice's aided inject feature is only compatible with function Object() injection. We have annotated the key parameter with @Assisted since it will be given at creation rather than by the container.

Now, in the child's protocol, we construct a Factory interface that accepts the key and returns the Actor:

Import Akka. Actor.Actor;
public class ConfiguredChildActorProtocol {


  public static class GetConfig {}
  public interface Factory {
    public Actor create(String key);
  }
}
You can also try this code with Online Java Compiler
Run Code

 

akka configuration

Configuration

The Play application configuration file is used to read the default actor system setup. For example, to specify the application actor system's default dispatcher, add the following lines to the conf/application.conf file:

Akka.actor.default-dispatcher.fork-join-executor.parallelism-max = 64
Akka.actor.debug.receive = on

Changing configuration prefix

You can instruct Play to load its Akka settings from another place if you wish to utilize the Akka.* settings for another Akka actor system.

"my-akka" = play.akka.config

 

Settings will now be read from the my-Akka prefix rather than the Akka prefix.

my-Akka.actor.default-dispatcher.fork-join-executor.parallelism-max = 64
my-Akka.actor.debug.receive = on

Built-in actor system name

The Play actor system's default name is applied. You may alter this by adding the following line to conf/application.conf:

Play.Akka.actor-system = "custom-name"

Frequently Asked Questions

What is Akka?

Akka is a free and open-source library and toolset. It is employed in the development of concurrent, distributed, and fault-tolerant applications. This library is compatible with any JVM (Java Virtual Machine) supported language. 

What is an Actor in Akka?

An actor is a message-passing entity that communicates with other actors. Each Actor has their own state and behavior. Everything is an object in object-oriented programming, just as everything is an actor in an actor-based system.

What is Akka ActorSystem?

In the actor hierarchy, the ActorSystem is a root actor. An ActorSystem is a hierarchical collection of actors with shared configuration, such as dispatchers, deployments, remote capabilities, and addresses. It is also the starting point for developing or searching for actors. It is a generic class that extends the ActorRefFactory trait.

What are the components of the Akka ActorSystem?

The components of the Akka Actor System are Event System, Scheduler, System Guardian Actor, User Guardian Actor, Dead Letter Office, and Configuration.

How is Akka ActorSystem Configuration Used?

ActorSystem has a configuration component for configuring applications. You can get to it using your actor system.

Conclusion

In this article, we learned about Integration with Akka and its employment as an Actor Model/System.

After reading about Integration with Akka, are you not feeling excited to read/explore more articles on the topic of Ruby? Don't worry; Coding Ninjas has you covered. To learn, see Software Developer 2 at Microsoft, Descriptors in Python, and BorderLayout in Java.

Refer to our Guided Path on Coding Ninjas Studio to upskill yourself in Data Structures and AlgorithmsCompetitive ProgrammingJavaScriptSystem Design, and many more! 

Do upvote our blogs if you find them helpful and engaging!

Live masterclass