Scala 来自枚举的Akka远程参与者异常
下面的代码包含一个简单的Akka remote actors示例,其中包含两个应用程序,Scala 来自枚举的Akka远程参与者异常,scala,akka,Scala,Akka,下面的代码包含一个简单的Akka remote actors示例,其中包含两个应用程序,ChipShop(服务器)和Customer(客户端)。它可以正常工作,客户发送打印出来的订单,但是如果我在ChipShopOrder中切换实现以使用枚举,那么我会得到一个异常(java.io.IOException:意外异常类型)。为什么会这样 例外情况: [INFO] [06/21/2012 19:40:54.1] [main] [ActorSystem(ShopSystem)] REMOTE: Remo
ChipShop
(服务器)和Customer
(客户端)。它可以正常工作,客户发送打印出来的订单,但是如果我在ChipShopOrder
中切换实现以使用枚举,那么我会得到一个异常(java.io.IOException:意外异常类型)。为什么会这样
例外情况:
[INFO] [06/21/2012 19:40:54.1] [main] [ActorSystem(ShopSystem)] REMOTE: RemoteServerStarted@akka://ShopSystem@127.0.0.1:2552
[INFO] [06/21/2012 19:41:03.692] [ShopSystem-7] [ActorSystem(ShopSystem)] REMOTE: RemoteClientStarted@akka://CustomerSystem@127.0.0.1:2553
[ERROR] [06/21/2012 19:41:03.796] [ShopSystem-3] [ActorSystem(ShopSystem)] REMOTE: RemoteServerError@akka://ShopSystem@127.0.0.1:2552] Error[java.io.IOException:unexpected exception type
at java.io.ObjectStreamClass.throwMiscException(ObjectStreamClass.java:1518)
at java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1097)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1780)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at scala.collection.mutable.HashTable$class.init(HashTable.scala:81)
at scala.collection.mutable.HashMap.init(HashMap.scala:45)
at scala.collection.mutable.HashMap.readObject(HashMap.scala:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1004)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1866)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at akka.serialization.JavaSerializer$$anonfun$1.apply(Serializer.scala:121)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:57)
at akka.serialization.JavaSerializer.fromBinary(Serializer.scala:121)
at akka.serialization.Serialization.deserialize(Serialization.scala:73)
at akka.remote.MessageSerializer$.deserialize(MessageSerializer.scala:21)
at akka.remote.RemoteMessage.payload(RemoteTransport.scala:210)
at akka.remote.RemoteMarshallingOps$class.receiveMessage(RemoteTransport.scala:276)
at akka.remote.netty.NettyRemoteTransport.receiveMessage(NettyRemoteSupport.scala:29)
at akka.remote.netty.RemoteServerHandler.messageReceived(Server.scala:178)
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75)
at akka.remote.netty.RemoteServerHandler.handleUpstream(Server.scala:150)
at org.jboss.netty.channel.StaticChannelPipeline.sendUpstream(StaticChannelPipeline.java:366)
at org.jboss.netty.channel.StaticChannelPipeline$StaticChannelHandlerContext.sendUpstream(StaticChannelPipeline.java:528)
at org.jboss.netty.handler.execution.ChannelUpstreamEventRunnable.run(ChannelUpstreamEventRunnable.java:44)
at org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor$ChildExecutor.run(OrderedMemoryAwareThreadPoolExecutor.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
要运行,请先启动ChipShop应用程序,然后启动Customer应用程序。
资料来源:
我猜这和阿克卡完全无关。删除所有Akka内容,只需将anOrder输出到ObjectOutputStream,然后从那里读入即可。除此之外,这可能与以下因素有关:你是对的,我可以用OOS进行复制。谢谢你的链接。我想这是一个Scala bug,我还没有解释它的状态。Akka允许您定义自己的序列化程序,这样您就可以轻松地为自己的消息定义一个序列化程序,并在那里处理封送和解封。
import com.typesafe.config.ConfigFactory
import akka.actor.{ ActorSystem, Actor, Props }
object Configs{
val customerConfig = ConfigFactory.parseString( """
akka.actor.provider = akka.remote.RemoteActorRefProvider
akka.remote.netty.hostname = "127.0.0.1"
akka.remote.netty.port = 2553
""")
val shopConfig = ConfigFactory.parseString( """
akka.actor.provider = akka.remote.RemoteActorRefProvider
akka.remote.netty.hostname = "127.0.0.1"
akka.remote.netty.port = 2552
""")
}
class ChipShopOrder extends Serializable{
// - Working implementation -
trait Food
case object Chips extends Food
case object Fish extends Food
case class OrderableItem(item: Food, quantity: Int)
//----------- End -----------
// -- Broken implementation --
// object Food extends Enumeration{
// type Food = Value
// val Chips, Fish, Sausage = Value
// }
// import Food._
// case class OrderableItem(item: Food.Value, quantity: Int)
//----------- End ------------
case class CustomerOrder(items: Seq[OrderableItem])
val anOrder = CustomerOrder(Seq(
OrderableItem(Chips, 2), OrderableItem(Fish, 1)
))
}
object Customer extends App{
val system = ActorSystem("CustomerSystem", Configs.customerConfig)
val shopAddress = "akka://ShopSystem@127.0.0.1:2552/user/Staff"
system.actorFor(shopAddress) ! new ChipShopOrder().anOrder
}
object ChipShop extends App{
class Staff extends Actor{
def receive = { case order => println("Received: "+order) }
}
ActorSystem("ShopSystem", Configs.shopConfig).actorOf(Props[Staff], "Staff")
}