来自Enum的Akka远程演员例外

时间:2012-06-21 18:46:18

标签: scala akka

下面的代码包含一个带有两个应用程序的简单Akka远程actor示例,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应用程序,然后启动客户应用程序。 来源:

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")
}

0 个答案:

没有答案