Scala编译器和JVM对加载Akka的版本存在分歧

Scala编译器和JVM对加载Akka的版本存在分歧,scala,constructor,akka,Scala,Constructor,Akka,编辑:为了澄清这一点,编译器和运行时似乎对类路径上的Akka版本存在分歧。除此之外,编译器看到新方法,但运行时引发了NoSuchMethodError,当我稍后尝试调用ActorContext.children(编译器看到它,但JVM引发了NoSuchMethod)时,我也会遇到同样的错误。这个问题可能比阿克卡更普遍 我已经做了mvn clean并多次检查了我的Scala REPL版本 原始问题: 版本2.2.1(我正在使用的版本)的and表示,具有构造函数参数的参与者应按如下方式构建: imp

编辑:为了澄清这一点,编译器和运行时似乎对类路径上的Akka版本存在分歧。除此之外,编译器看到新方法,但运行时引发了
NoSuchMethodError
,当我稍后尝试调用
ActorContext.children
(编译器看到它,但JVM引发了
NoSuchMethod
)时,我也会遇到同样的错误。这个问题可能比阿克卡更普遍

我已经做了
mvn clean
并多次检查了我的Scala REPL版本

原始问题:

版本2.2.1(我正在使用的版本)的and表示,具有构造函数参数的参与者应按如下方式构建:

import akka.actor.Actor
import akka.actor.Props
import akka.actor.ActorSystem

class MyActor(one: Int, two: Double, three: String) extends Actor {
  def receive = {
    case "test" => println("%d %g %s".format(one, two, three))
  }
}

val system = ActorSystem("MyActorSystem")
val actor = system.actorOf(Props(classOf[MyActor], 1, 2.0, "three"))
虽然这会编译,但会引发
java.lang.NoSuchMethodError:akka.actor.Props$.apply(Ljava/lang/Class;Lscala/collection/Seq;)Lakka/actor/Props尝试运行时出现异常

在REPL上运行它会导致

<console>:12 error: type mismatch;
 found   : Class[MyActor](classOf[$MyActor])
 required: () => akka.actor.Actor
       val actor = system.actorOf(Props(classOf[MyActor], 1, 2.0, "three"))
                                               ^
它在REPL上不加评论地工作,并且具有

[warn] test.scala:10 method apply in object Props is deprecated: use Props.withDispatcher and friends
    val actor = system.actorOf(Props(classOf[MyActor], 1, 2.0, "three"))
                               ^
编译器中的警告。文档和文档都证实了这种反对意见,说闭包技术(我正在使用的)会导致不可序列化的参与者

我不想使用不推荐的东西,尤其是因为我刚刚开始使用这个库。我不理解关于
Props.withDispatcher
和friends的评论,因为我只想使用默认的dispatcher,至少现在是这样。有没有这样的例子

编辑:我的pom.xml如下所示。我已经注释掉了所有的测试,因为没有任何版本的
scalatest
可以与scala2.10.2一起使用。我已经多次清理了
target
目录:任何地方都没有其他Scala版本的迹象(而且从来没有任何其他版本的Akka)


4.0.0
阴谋技巧
2013
绘图技巧
阴谋技巧
1.0-快照
罐子
Apache软件许可证,版本2.0
http://www.apache.org/licenses/LICENSE-2.0.txt
回购
1.6
1.6
UTF-8
2.10
2.10.2
org.scala-lang
scala图书馆
${scala.version}
org.mozilla
犀牛
1.7R4
org.apache.avro
阿夫罗
1.7.5
org.codehaus.jackson
jackson core asl
1.9.13
org.codehaus.jackson
杰克逊地图绘制者
1.9.13
com.typesafe.akka
akka-actor_2.10
2.2.1
com.typesafe.akka
akka-remote_2.10
2.2.1
com.typesafe.akka
akka-testkit_2.10
2.2.1
src/main/scala
net.alchim31.maven
scala maven插件
3.1.3
编译
-贬低
-特征
-从属文件
${project.build.directory}/.scala\u依赖项
增量的
真的
org.apache.maven.plugins
maven jar插件
2.4
org.plotsmanship.Main
真的
/lib
org.apache.maven.plugins
maven依赖插件
包裹
复制依赖项
目标/库

尝试查看类路径中的库。即使指定运行scala-cp的类路径,scala也会自动将scala标准库和其他库添加到scala home的lib目录中。请查收

尝试在main中编写一段代码来打印类路径。它将帮助您找到正在加载的内容。这是用java编写的,但它会有所帮助

我复制并粘贴了您的第一个示例,就像API中指定的一样,并使用build.sbt构建了它:

name := "My Project"
version := "1.0"
scalaVersion := "2.10.2"
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
libraryDependencies ++= {
    Seq(
      "com.typesafe.akka" %% "akka-actor" % "2.2.1",
      "com.typesafe.akka" %% "akka-remote" % "2.2.1",
      "com.typesafe.akka" %% "akka-testkit" % "2.2.1"
    )
}
它就像一个符咒:

$ sbt clean compile run
[info] Loading global plugins from ~/.sbt/plugins
...........
[success] Total time: 4 s, completed Sep 13, 2013 6:03:05 PM
[info] Running MyActor 
1 2.00000 three

如果您使用akka 2.2.x和scala 2.10.y,您可能会遇到一个问题:查看scala/lib目录,您会在那里看到akka-actors.jar,这是akka的2.1.z版本(只需查看清单或一些典型类中的内部)。因此,如果您像这样运行应用程序:

import akka.actor.Actor
import akka.actor.Props
import akka.actor.ActorSystem

class MyActor(one: Int, two: Double, three: String) extends Actor {
  def receive = {
    case "test" => println("%d %g %s".format(one, two, three))
  }
}

val system = ActorSystem("MyActorSystem")
val actor = system.actorOf(Props(classOf[MyActor], 1, 2.0, "three"))
scala-cp$YourLibs:akka-actors-2.2.x。。。
akka的2.1 jar将首先(自动)添加,并且不会被类路径中的2.2覆盖

解决方法:

不使用scala包装器手动运行它:

java-cp$ScalaHome/lib/scala library.jar:$AkkaHome/$Akka_2.2_jars YourMainClass

另外,我不明白为什么akka jar附带scala

不,即使我包含了这些库,我的示例也会以同样的方式运行。(例如,从REPL-as
scala-cp akka-actor_2.10-2.2.1.jar:akka-testkit_2.10-2.2.1.jar:akka-remote_2.10-2.2.1.jar
或编译到Maven项目中)我认为您的类路径中首先有一个旧版本的akka。尝试使用my build.sbt并检查类路径中正在加载的内容。如果您的pom.xml引用了依赖于akka 2.1的库,它将被加载。pom下载的唯一库是akka 2.2.1。当然,如果我将它们显式地加载到类路径上,就像我前面评论中的示例一样,那么我就不会得到错误的版本。(如果拼写错误,我可能不会加载Akka,但我不会得到错误的Akka。)我认为在您的澄清中,最好给出编译和运行环境的详细信息。这不是akka问题,而是类路径问题。公共关系
$ sbt clean compile run
[info] Loading global plugins from ~/.sbt/plugins
...........
[success] Total time: 4 s, completed Sep 13, 2013 6:03:05 PM
[info] Running MyActor 
1 2.00000 three