Reputation: 31
I am setting akka cluster (using akka library version 2.3.9 ) with one master actor and multiple worker actor. Master Actor is configured with pool cluster aware router.
Deploying application with forming 4 cluster nodes. Initially all the nodes are joining to cluster properly but after few minutes nodes are disassociating to cluster and forming their own cluster.
**Getting below warn message logged when enabling remote debug logging -**
**ERROR] []** [ClusterSystem-akka.remote.default-remote-dispatcher-23] [akka.tcp://ClusterSystem
@localhost:2551/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2FClusterSystem%40localhost%3A2552-0/en
dpointWriter] AssociationError [akka.tcp://ClusterSystem@localhost:2551] -> [akka.tcp://ClusterSystem@localhost:2552
]: **Error [Failed to write message to the transport] [
akka.remote.EndpointException: Failed to write message to the transport
Caused by: java.lang.IllegalArgumentException: Can't serialize object of type class org.springframework.context.supp
ort.ClassPathXmlApplicationContext**
at akka.cluster.protobuf.ClusterMessageSerializer.toBinary(ClusterMessageSerializer.scala:74)
at akka.serialization.Serialization$$anonfun$serialize$1.apply(Serialization.scala:90)
at akka.serialization.Serialization$$anonfun$serialize$1.apply(Serialization.scala:90)
at scala.util.Try$.apply(Try.scala:161)
at akka.serialization.Serialization.serialize(Serialization.scala:90)
at akka.remote.serialization.DaemonMsgCreateSerializer.serialize(DaemonMsgCreateSerializer.scala:107)
at akka.remote.serialization.DaemonMsgCreateSerializer$$anonfun$propsProto$1$1.apply(DaemonMsgCreateSerializ
er.scala:56)
at akka.remote.serialization.DaemonMsgCreateSerializer$$anonfun$propsProto$1$1.apply(DaemonMsgCreateSerializ
er.scala:56)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractTraversable.map(Traversable.scala:105)
at akka.remote.serialization.DaemonMsgCreateSerializer.propsProto$1(DaemonMsgCreateSerializer.scala:56)
at akka.remote.serialization.DaemonMsgCreateSerializer.toBinary(DaemonMsgCreateSerializer.scala:62)
at akka.remote.MessageSerializer$.serialize(MessageSerializer.scala:36)
at akka.remote.EndpointWriter$$anonfun$serializeMessage$1.apply(Endpoint.scala:842)
at akka.remote.EndpointWriter$$anonfun$serializeMessage$1.apply(Endpoint.scala:842)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:57)
at akka.remote.EndpointWriter.serializeMessage(Endpoint.scala:841)
at akka.remote.EndpointWriter.writeSend(Endpoint.scala:742)
at akka.remote.EndpointWriter$$anonfun$2.applyOrElse(Endpoint.scala:717)
at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
at akka.remote.EndpointActor.aroundReceive(Endpoint.scala:410)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
at akka.actor.ActorCell.invoke(ActorCell.scala:487)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:254)
at akka.dispatch.Mailbox.run(Mailbox.scala:221)
at akka.dispatch.Mailbox.exec(Mailbox.scala:231)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1253)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1346)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Upvotes: 2
Views: 399
Reputation: 254
I've faced with the same issue in my java-spring-akka application. I use IndirectActorProducer for instantiating actors as bean (with scope prototype). This producer contains Spring ApplicationContext. Such way works perfect with cluster sharding. But the simple pooled router in cluster environment (round-robin-pool in my case) tries to send Props with IndirectActorProducer (and with ApplicationContext) through cluster. I can suggest some hack's workaround, which works for me: create custom serializer and define it to the "ConfigurableApplicationContext" class. See the example below:
public class SpringContextSerializer extends JSerializer {
private static ConfigurableApplicationContext configurableApplicationContext;
public static void init(ConfigurableApplicationContext configurableApplicationContext) {
SpringContextSerializer.configurableApplicationContext = configurableApplicationContext;
}
public SpringContextSerializer() {
if (configurableApplicationContext == null) {
throw new RuntimeException("Serializer mist be initialized before creating.");
}
}
@Override
public int identifier() {
return getClass().toString().hashCode();
}
@Override
public byte[] toBinary(Object o) {
return new byte[0];
}
@Override
public boolean includeManifest() {
return false;
}
@Override
public Object fromBinaryJava(byte[] bytes, Class<?> manifest) {
return configurableApplicationContext;
}
}
Config:
akka.actor {
serializers {
context = "ru.ddg.elleps.hubcache.integration.SpringContextSerializer"
}
serialization-bindings {
"org.springframework.context.annotation.AnnotationConfigApplicationContext" = context
}
}
Also, you have to initialize serializer with container befor an ActorSystem is started.
Upvotes: 1