不能在AKKA演员之间发送和接收除字符串之外的其他消息

时间:2014-04-29 17:09:38

标签: scala actor playframework-2.2

如果尝试运行使用akka的应用程序,则会显示以下错误:

play.api.i18n.Messages$MessagesParser$$anon$1: Configuration error[`=' expected but `
' found]
at play.api.i18n.Messages$MessagesParser.parse(Messages.scala:219) ~[play_2.10-    2.2.1.jar:2.2.1]
at play.api.i18n.MessagesPlugin$$anonfun$play$api$i18n$MessagesPlugin$$loadMessages$1.apply(Messages.scala:286) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.i18n.MessagesPlugin$$anonfun$play$api$i18n$MessagesPlugin$$loadMessages$1.apply(Messages.scala:285) ~[play_2.10-2.2.1.jar:2.2.1]
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
at scala.collection.immutable.List.foreach(List.scala:318) ~[scala-library.jar:na]
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:na]
at scala.collection.AbstractTraversable.map(Traversable.scala:105) ~[scala-library.jar:na]
at play.api.i18n.MessagesPlugin.play$api$i18n$MessagesPlugin$$loadMessages(Messages.scala:285) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.i18n.MessagesPlugin.messages$lzycompute(Messages.scala:296) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.i18n.MessagesPlugin.messages(Messages.scala:292) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.i18n.MessagesPlugin.onStart(Messages.scala:309) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:88) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:88) ~[play_2.10-2.2.1.jar:2.2.1]
at scala.collection.immutable.List.foreach(List.scala:318) ~[scala-library.jar:na]
at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:88) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.Play$$anonfun$start$1.apply(Play.scala:88) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.Play$$anonfun$start$1.apply(Play.scala:88) ~[play_2.10-2.2.1.jar:2.2.1]
at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10-2.2.1.jar:2.2.1]
at play.api.Play$.start(Play.scala:87) ~[play_2.10-2.2.1.jar:2.2.1]
at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:139) ~[play_2.10-2.2.1.jar:2.2.1]
at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:112) ~[play_2.10-2.2.1.jar:2.2.1]
at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:112) ~[play_2.10-2.2.1.jar:2.2.1]
at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:110) ~[play_2.10-2.2.1.jar:2.2.1]
at scala.util.Success.flatMap(Try.scala:200) ~[scala-library.jar:na]
at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:110) ~[play_2.10-2.2.1.jar:2.2.1]
at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:102) ~[play_2.10-2.2.1.jar:2.2.1]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library.jar:na]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361) ~[scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) ~[scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) ~[scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) ~[scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) ~[scala-library.jar:na]

我构建了一个case类,目的是将它作为消息发送给Actor:

package messages

object ErrorHandlerMessages {
  case class Error (message:String, exception:Exception)
}

当我运行我的应用程序并尝试将消息发送给我的演员时......:

class ErrorHandlerActor extends Actor {

  val log = Logging(context.system, this)

  def receive: Receive = {
    case e:Error => handleError(e)
    case _ => handleError(Error("UNEXPECTED ERROR!",new Exception("UNEXPECTED ERROR! The Error Handler received an unknown message!")))
  }

  def handleError(e:Error):SimpleResult = {
    log.error(e.message,e.exception)
    BadRequest(Json.obj("status" ->"Error", "message" -> e.message))
  }
}

...它会抛出您在上面看到的错误。

当我稍微更改代码以便我的actor收到一个String时效果很好。 有人能告诉我我错过了什么吗?

提前致谢

这里有一段有用的代码:

发送方

- >

Await.result(errorHandlerActor ? "Couldnt validate json input correctly!",timeout.duration).asInstanceOf[SimpleResult]
接收方

- >

class ErrorHandlerActor extends Actor {

  val log = Logging(context.system, this)

  def receive: Receive = {
    case e:String => handleError(e)
    case _ => handleError("UNEXPECTED ERROR!"/*,new Exception("UNEXPECTED ERROR! The Error Handler received an unknown message!")*/)
  }

  def handleError(e:String) = {
    log.error(e)
    sender ! BadRequest(Json.obj("status" ->"Error"))
  }
}

这里加载的消息文件:

# Default messages

# --- Constraints
constraint.required=Required
constraint.min=Minimum value: {0}
constraint.max=Maximum value: {0}
constraint.minLength=Minimum length: {0}
constraint.maxLength=Maximum length: {0}
constraint.email=Email

# --- Formats
format.date=Date (''{0}'')
format.numeric=Numeric
format.real=Real

# --- Errors
error.invalid=Invalid value
error.invalid.java.util.Date=Invalid date value
error.required=This field is required
error.number=Numeric value expected
error.real=Real number value expected
error.real.precision=Real number value with no more than {0} digit(s) including {1} decimal(s) expected
error.min=Must be greater or equal to {0}
error.min.strict=Must be strictly greater than {0}
error.max=Must be less or equal to {0}
error.max.strict=Must be strictly less than {0}
error.minLength=Minimum length is {0}
error.maxLength=Maximum length is {0}
error.email=Valid email required
error.pattern=Must satisfy {0}

error.expected.date=Date value expected
error.expected.date.isoformat=Iso date value expected
error.expected.jodadate.format=Joda date value expected
error.expected.jsarray=Array value expected
error.expected.jsboolean=Boolean value expected
error.expected.jsnumber=Number value expected
error.expected.jsobject=Object value expected
error.expected.jsstring=String value expected
error.expected.jsnumberorjsstring=String or number expected
error.expected.keypathnode=Node value expected

error.path.empty=Empty path
error.path.missing=Missing path
error.path.result.multiple=Multiple results for the given path

2 个答案:

答案 0 :(得分:3)

异常似乎是由国际化插件引起的。特别是在这里:

  

在   play.api.i18n.MessagesPlugin.play $ API $国际化$ MessagesPlugin $$ loadMessages(Messages.scala:285)   〜[play_2.10-2.2.1.jar:2.2.1] at   play.api.i18n.MessagesPlugin.messages $ lzycompute(Messages.scala:296)   〜[play_2.10-2.2.1.jar:2.2.1] at   play.api.i18n.MessagesPlugin.messages(Messages.scala:292)   〜[play_2.10-2.2.1.jar:2.2.1] at   play.api.i18n.MessagesPlugin.onStart(Messages.scala:309)   〜[play_2.10-2.2.1.jar:2.2.1]

Messages.scala中的第285行正在尝试从文件中加载消息

private def loadMessages(file: String): Map[String, String] = {
    app.classloader.getResources(file).asScala.toList.reverse.map { messageFile =>
      new Messages.MessagesParser(messageFile.asInput, messageFile.toString).parse.map { message =>
        message.key -> message.pattern
      }.toMap
    }.foldLeft(Map.empty[String, String]) { _ ++ _ }
  }

您可以在此函数中添加断点,以查看插件尝试读取的格式错误的文件是什么?

仅供参考:默认行为是尝试使用“messages.lang”模式加载所有文件,其中“lang”类似于“en”,“fr”等(例如messages.en,messages.it)

答案 1 :(得分:1)

经过很长一段时间搜索该错误后,由于" vptheron"谁指出了我正确的方向。

我放了多个自定义"消息"具有不同后缀(en,de,fr等)的文件和默认的没有后缀的文件" conf"编译后通常最终在类路径中的目录,但是../target/scala-2.10/classes下唯一没有的文件是"消息"文件。

我忘记了我创建了一个名为" messages"在类路径(几周前)。因此,当编译器尝试复制消息文件时,这是冲突的。

再次感谢vptheron。我希望这将有助于将来的人。