I have an OrderManagerActor that accepts messages from classes that implement the Message interface. This interface is implemented by the following classes CreateOrderMessage, DeleteOrderMessage, UpdateOrderStatusMessage.
When trying to register the createReceive() method in OrderManagerActor
@Override
public Receive<Message> createReceive() {
return ReceiveBuilder.create()
.onMessage(CreateOrderMessage.class, this::createOrder)
.build();
}
I get the following:
reason: Incompatible types: Behavior<Message> is not convertible to Behavior<Object>
Well, I can make sure that all the messages that my Actor receives are Objects, but it seems to me that this will not be entirely correct
OrderManagerActor class
package actor;
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.*;
import message.Message;
import message.impl.CreateOrderMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderManagerActor extends AbstractBehavior<Message> {
private final Logger loggerFactory = LoggerFactory.getLogger(OrderManagerActor.class);
public OrderManagerActor(ActorContext<Message> context) {
super(context);
}
@Override
public Receive<Message> createReceive() {
return ReceiveBuilder.create()
.onMessage(CreateOrderMessage.class, this::createOrder)
.build();
}
private Behavior<Message> createOrder(CreateOrderMessage createOrderMessage) {
loggerFactory.info(createOrderMessage.toString());
return this;
}
public static Behavior<Message> createBehavior() {
return Behaviors.setup(OrderManagerActor::new);
}
}
Message interface:
package message;
public interface Message {
}
Message interface implementation:
package message.impl;
import message.Message;
public class CreateOrderMessage implements Message {
private String id;
public CreateOrderMessage(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
UPDATE!
I fixed it, it was need to use a newReceiveBuilder builder.
@Override
public Receive<Message> createReceive() {
return ReceiveBuilder.create()
.onMessage(CreateOrderMessage.class, this::createOrder)
.build();
}
Good that you got it sorted using the factory method, which has an unbounded type parameter allowing the compiler to infer/fill in the type for you.
It is important to note that Behavior<Message>
is in fact not generally convertible to Behavior<Object>
.
A Behavior<Message>
means that actors spawned with the behavior can handle messages of type Message
and subtypes of Message
. Object
is not a subtype but a supertype of Message
and would mean that you can send any object you want to the actor, which would fail because that is now what it can handle.